我有一个对象列表。我想在这个列表中找到一个(第一个或任何)对象,它的属性(或方法结果-无论什么)等于value。

找到它的最好方法是什么?

下面是一个测试用例:

class Test:
    def __init__(self, value):
        self.value = value

import random

value = 5

test_list = [Test(random.randint(0,100)) for x in range(1000)]

# that I would do in Pascal, I don't believe it's anywhere near 'Pythonic'
for x in test_list:
    if x.value == value:
        print "i found it!"
        break

我认为使用生成器和reduce()不会有任何区别,因为它仍然会遍历列表。

附:等式到值只是一个例子。当然,我们想要得到一个满足任何条件的元素。


当前回答

老问题,但我经常使用这个(对于3.8版本)。它在语法上有点复杂,但它比顶部的答案更有优势,因为您可以通过简单地删除[0]来检索结果列表(如果有多个),如果没有找到任何结果,它仍然默认为None。对于任何其他条件,只需将x.value==value更改为您所寻找的值。

_[0] if (_:=[x for x in test_list if x.value==value]) else None

其他回答

老问题,但我经常使用这个(对于3.8版本)。它在语法上有点复杂,但它比顶部的答案更有优势,因为您可以通过简单地删除[0]来检索结果列表(如果有多个),如果没有找到任何结果,它仍然默认为None。对于任何其他条件,只需将x.value==value更改为您所寻找的值。

_[0] if (_:=[x for x in test_list if x.value==value]) else None

举个简单的例子: 我们有下面的数组

li = [{"id":1,"name":"ronaldo"},{"id":2,"name":"messi"}]

现在,我们想在数组中找到id = 1的对象

接下来使用方法与列表理解

next(x for x in li if x["id"] == 1 )

使用列表推导式并返回第一项

[x for x in li if x["id"] == 1 ][0]

自定义函数

def find(arr , id):
    for x in arr:
        if x["id"] == id:
            return x
find(li , 1)

输出上述所有方法是{'id': 1, 'name': 'ronaldo'}

你可以这样做

dict = [{
   "id": 1,
   "name": "Doom Hammer"
 },
 {
    "id": 2,
    "name": "Rings ov Saturn"
 }
]

for x in dict:
  if x["id"] == 2:
    print(x["name"])

这就是我用来在一长串对象中找到对象的方法。

你也可以通过你的Test类的__eq__方法来实现丰富的比较,并在操作符中使用。 不确定这是否是最好的独立方式,但是如果您需要基于其他地方的值比较Test实例,那么这可能会很有用。

class Test:
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
        """To implement 'in' operator"""
        # Comparing with int (assuming "value" is int)
        if isinstance(other, int):
            return self.value == other
        # Comparing with another Test object
        elif isinstance(other, Test):
            return self.value == other.value

import random

value = 5

test_list = [Test(random.randint(0,100)) for x in range(1000)]

if value in test_list:
    print "i found it"

我刚刚遇到了一个类似的问题,并针对列表中没有对象满足要求的情况设计了一个小优化。(对于我的用例,这导致了主要的性能改进):

除了列表test_list,我还保留了一个额外的集test_value_set,它由我需要筛选的列表中的值组成。所以这里agf解的else部分很快。