2014-09-24 74 views
1

在下面的代码中,我创建了一个包含三个对象的列表,并使用变量a,b,c通过它们的id存储第一个,第二个,然后第三个对象,但是当我尝试将第三个对象存储在变量c中,它存储第二个和第三个对象的列表。Python:通过id从对象列表中检索

class Obj1(): 
    id='obj1' 

class Obj2(): 
    id='obj2' 

class Obj3(): 
    id='obj3' 

list1=[Obj1(),Obj2(),Obj3()] 

a=list1[id=="obj1"] 
print a 

b=list1[id!='obj1'] 
print b 

c=list1[id!='obj1'and id!='obj2':] 
print c 

当我运行这段代码,我得到:

<__main__.Obj1 instance at 0x02AD5DA0> 
<__main__.Obj2 instance at 0x02AD9030> 
[<__main__.Obj2 instance at 0x02AD9030>, <__main__.Obj3 instance at 0x02AD90A8>] 

为什么变量c包含两个对象?

回答

2

使用字典可能是在这种情况下,最好的办法,由迈扎特提及。然而,你可以用类似的方式去做你想要使用列表解析的东西:

a = [e for e in list1 if e.id == "obj1"] 
print a 

b = [e for e in list1 if e.id != "obj1"] 
print b 

c = [e for e in list1 if e.id != "obj1" and e.id != "obj2"] 
# Or: 
# [e for e in list1 if e.id not in ("obj1", "obj2")] 
print c 
+0

除了我提供的例子之外,我所面临的主要问题是我需要从对象内部的对象列表中提取id此解决方案效果最佳。无需将列表转换为字典,您的代码是最高效的,并且完全符合我的需求。 – Rmor91 2014-09-24 04:02:15

+0

我会添加一件东西,从列表中检索对象:a = [e for list1中的e,如果e.id!=“obj1”] [0]。否则变量存储1个对象的列表 – Rmor91 2014-09-24 04:31:02

+0

很高兴帮助。请注意,对于您构建的每个新列表,列表理解必须迭代列表中的每个元素。对于小列表来说很好,但是如果你有很大的列表,它可能会很慢。一个简单的字典查询可以在不变的时间内运行,所以如果可能的话,这对于大量的对象来说更好。 – JKillian 2014-09-24 04:31:54

1

你list1的包含3个要素:

>>> list1 
[<__main__.Obj1 instance at 0x103437440>, <__main__.Obj2 instance at 0x1034377a0>,   <__main__.Obj3 instance at 0x103437320>] 
>>> id!='obj1' 
True 
>>> id!='obj2' 
True 
>>> True and True 
True 
>>> list1[True:] 
[<__main__.Obj2 instance at 0x1034377a0>, <__main__.Obj3 instance at 0x103437320>] 
>>> 

真是1和False是0的索引:

这里是例如:

>>> ls = [1,2] 
>>> ls[True] 
2 
>>> ls[False] 
1 
>>> 

所以,列表[真:]是等于从第一个元素到最后一个元素的列表[1:]。

在你的情况下,列表1中的最后两个元素。

2

我敢打赌你对Python很熟悉。

id!='obj1'and id!='obj2'返回在Python中等于1的真,也就是说,c=list1[id!='obj1'and id!='obj2':]等于c=list1[1:],这当然有两个对象。

顺便说一句,id是一个内置函数的名称。请避免使用它作为varible的名称。

2

你应该用字典来代替:

obj1 = Obj1() 
obj2 = Obj2() 
obj3 = Obj3() 
list1 = {obj1.id: obj1, obj2.id: obj2, obj3.id: obj3} 

然后访问您的对象是这样的:

a = list1[obj1.id] 
b = list1[obj2.id] 
c = list1[obj3.id] 
+0

顺便说一句,你不要回答他正在试图找到的东西:)而他选择这个答案真的吗?他的问题是:为什么变量c包含两个对象? – 2014-09-24 03:47:37

+0

尽管其他答案解释了如何将布尔值作为整数使用,但此答案最好解决了使用对象ID从列表/字典中进行选择的主要问题。 – Rmor91 2014-09-24 03:48:30

+2

当您了解他正在尝试执行的操作时,它仍然是有效的答案将他引导到正确的路径。 – 2014-09-24 03:48:54