在Python中search对象列表
假设我正在创build一个类似于C风格结构的简单类来保存数据元素。 我想弄清楚如何search一个属性等于一定值的对象列表。 下面是一个简单的例子来说明我正在尝试做什么。
例如:
class Data: pass myList = [] for i in range(20): data = Data() data.n = i data.n_squared = i * i myList.append(data)
我将如何去searchmyList列表,以确定它是否包含n == 5的元素?
我一直在谷歌searchPython文档,我想我可以用列表理解,但我不知道。 我可能会补充说,我不得不使用Python 2.4.3,所以任何新的gee-whiz 2.6或3.xfunction都不可用。
您可以通过列表理解获得所有匹配元素的列表:
[x for x in myList if xn == 30] # list of all elements with .n==30
如果你只是想确定列表是否包含任何匹配的元素并且相对有效地执行,那么你可以这样做
def contains(list, filter): for x in list: if filter(x): return True return False if contains(myList, lambda x: xn == 3) # True if any element has .n==3 # do stuff
简单,优雅,强大:
一个生成器expression式与一个内置的…(python 2.5+)
any(x for x in mylist if xn == 10)
使用Python的any()
内置函数,定义如下:
any(iterable)
->
如果迭代器的任何元素为真,则返回True。 相当于:
def any(iterable): for element in iterable: if element: return True return False
为了完整起见,我们不要忘记最可能发挥作用的最简单的事情:
for i in list: if in == 5: # do something with it print "YAY! Found one!"
filter(lambda x: xn == 5, myList)
[x for x in myList if xn == 30] # list of all matches any(xn == 30 for x in myList) # if there is any matches [i for i,x in enumerate(myList) if xn == 30] # indices of all matches def first(iterable, default=None): for item in iterable: return item return default first(x for x in myList if xn == 30) # the first match, if any
您可以使用in
查找集合中的项目,并使用列表理解来提取您感兴趣的字段。这适用于列表,集合,元组以及定义__contains__
或__getitem__
任何内容。
if 5 in [data.n for data in myList]: print "Found it"
也可以看看:
- 包含方法
- 在操作中
考虑使用字典:
myDict = {} for i in range(20): myDict[i] = i * i print(5 in myDict)
你应该添加一个__eq__
和一个__hash__
方法到你的Data
类,它可以检查__dict__
属性是否相等(相同的属性),然后如果它们的值是相等的。
如果你这样做,你可以使用
test = Data() test.n = 5 found = test in myList
in
关键字检查test
是否在myList
。
如果你只想要在Data
属性,你可以使用:
class Data(object): __slots__ = ['n'] def __init__(self, n): self.n = n def __eq__(self, other): if not isinstance(other, Data): return False if self.n != other.n: return False return True def __hash__(self): return self.n myList = [ Data(1), Data(2), Data(3) ] Data(2) in myList #==> True Data(5) in myList #==> False