在Python中的对象列表中搜索

时间:2012-03-01 06:14:21

标签: python

让我们假设以下对象:

class Test:
    id1 = ""
    id2 = ""
    id3 = ""

    def __init__(self,arg1,arg2,arg3):
        self.id1 = arg1
        self.id2 = arg2
        self.id3 = arg3

可以看出,这个类必须包含3个唯一ID。

t = []
t.append(Test(200,201,193))
t.append(Test(403,221,213))
t.append(Test(3,523,2003))

假设上面的代码,在列表t中找到id1 = 403,id2 = 221和id3 = 213的对象的最简单方法是什么?

提前致谢。

4 个答案:

答案 0 :(得分:2)

使用迭代进行比较。

matches = [i for i in t if i.id1 == id1 and i.id2 == id2 and i.id3 == id3]

如果你知道它就在那里而且只有一个,你可以这样做:

match = next(i for i in t if i.id1 == id1 and i.id2 == id2 and i.id3 == id3)

但请注意,如果没有此类项目,则会引发StopIterationnext可以采用默认值,因此,如果您不确定它是否存在,则可以指定默认值:

match = next((i for i in t if i.id1 == id1 and i.id2 == id2 and i.id3 == id3), None)

答案 1 :(得分:2)

如果您有很多对象并且需要多次找到匹配项,那么首先将它们预先处理为具有(id1,id2,id3)键的字典可能更有效。这样你就可以在O(1)中找到对象。

建立字典:

# In Python 2.7+
the_dict = {(o.id1, o.id2, o.id3) : o for o in objects}
# In Python 2.6-
the_dict = dict((o.id1, o.id2, o.id3),o) for o in objects)

然后在O(1)中找到对象:

the_dict[(id1,id2,id3)]

请注意,将对象放置为字典值不会复制它们(Python 从不隐式复制),因此您不必担心内存影响。

答案 2 :(得分:1)

>>> [x for x in t if x.id1==200 and x.id2==201 and x.id3==193]
[<__main__.Test object at 0x00BA3030>]

答案 3 :(得分:1)

如果您需要将对象存储在列表中(即,如果您不能使用dict并完全避免搜索),我会向{{{ 1}}将ID作为元组返回:

Test

然后,您可以简单地循环并检查您的ID元组以搜索:

class Test(object):
    ...
    def getids(self):
        return (self.id1, self.id2, self.id3)

这与清理界面一样“简单”。要加快速度,您应该使用字典而不是列表,并且可以一步检索对象:

for obj in t:
    if obj.getids() == (403, 221, 213):
        return obj

然后,您可以按ID检索对象,或以t = dict() obj = Test(403, 221, 213) t[obj.getids()] = obj # Store in dictionary, using ID as the key 中的任何一种方式检查它们是否存在:

t