在 Python 中搜索对象列表

让我们假设我正在创建一个简单的类,它的工作方式类似于 C 样式的结构,只保存数据元素。我试图找出如何搜索对象列表的对象的属性等于某个值。下面是一个简单的例子来说明我要做的事情。

例如:

class Data:
pass


myList = []


for i in range(20):
data = Data()
data.n = i
data.n_squared = i * i
myList.append(data)

如何搜索 myList 列表以确定它是否包含 n = = 5的元素?

我一直在谷歌和搜索 Python 文档,我想我可以用一个列表内涵来做这件事,但我不确定。顺便说一句,我必须使用 Python 2.4.3,所以任何新的 gee-whiz2.6或3.x 特性对我来说都是不可用的。

259598 次浏览

你应该添加一个 __eq__和一个 __hash__方法到你的 Data类,它可以检查 __dict__属性是否相等(相同的属性) ,然后如果他们的值也是相等的。

如果你这样做了,你可以使用

test = Data()
test.n = 5


found = test in myList

in关键字检查 test是否在 myList中。

如果只想在 Data中使用 n属性,可以使用:

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

你可以得到一个带有列表内涵的 所有匹配元素列表:

[x for x in myList if x.n == 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: x.n == 3)  # True if any element has .n==3
# do stuff
[x for x in myList if x.n == 30]               # list of all matches
[x.n_squared for x in myList if x.n == 30]     # property of matches
any(x.n == 30 for x in myList)                 # if there is any matches
[i for i,x in enumerate(myList) if x.n == 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 x.n == 30)          # the first match, if any

为了完整起见,我们不要忘记最简单的事情:

for i in list:
if i.n == 5:
# do something with it
print "YAY! Found one!"
filter(lambda x: x.n == 5, myList)

你可以使用 in在一个集合中查找一个项目,然后使用列表内涵提取你感兴趣的字段。这(适用于列表、集合、元组和任何定义 __contains____getitem__的内容)。

if 5 in [data.n for data in myList]:
print "Found it"

参见:

简洁,优雅,强大:

与内置... (python 2.5 +)结合的生成器表达式

any(x for x in mylist if x.n == 10)

使用 Python any()内置函数,其定义如下:

任意(可迭代) -> 如果迭代的任何元素为 True,则返回 True。等效于:

def any(iterable):
for element in iterable:
if element:
return True
return False

考虑使用字典:

myDict = {}


for i in range(20):
myDict[i] = i * i


print(5 in myDict)

另一种方法是使用 next ()函数。

matched_obj = next(x for x in list if x.n == 10)

结合使用以下列表内涵和 index方法:

data_n = 30
j = [data.n for data in mylist].index(data_n)
print(mylist[j].data.n == data_n)