在列表中查找属性等于某个值(满足任何条件)的对象

我有一个对象列表。我想在这个列表中找到一个(第一个或其他)对象,其属性(或方法result - whatever)等于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()不会有任何区别,因为它仍然会遍历列表。

value的方程只是一个例子。当然,我们想要得到一个满足任何条件的元素。

378906 次浏览
next((x for x in test_list if x.value == value), None)

这将从列表中获取匹配条件的第一项,如果没有匹配项则返回None。这是我喜欢的单表达式形式。

然而,

for x in test_list:
if x.value == value:
print("i found it!")
break

简单的循环中断版本完全是python的——它简洁、清晰、高效。要使它匹配单行程序的行为:

for x in test_list:
if x.value == value:
print("i found it!")
break
else:
x = None

如果你没有break跳出循环,这个函数会将None赋值给x

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

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

因为它没有被提到只是为了完成。 好的ol'过滤器过滤你的要过滤的元素

函数式编程

####### Set Up #######
class X:


def __init__(self, val):
self.val = val


elem = 5


my_unfiltered_list = [X(1), X(2), X(3), X(4), X(5), X(5), X(6)]


####### Set Up #######


### Filter one liner ### filter(lambda x: condition(x), some_list)
my_filter_iter = filter(lambda x: x.val == elem, my_unfiltered_list)
### Returns a flippin' iterator at least in Python 3.5 and that's what I'm on


print(next(my_filter_iter).val)
print(next(my_filter_iter).val)
print(next(my_filter_iter).val)


### [1, 2, 3, 4, 5, 5, 6] Will Return: ###
# 5
# 5
# Traceback (most recent call last):
#   File "C:\Users\mousavin\workspace\Scripts\test.py", line 22, in <module>
#     print(next(my_filter_iter).value)
# StopIteration




# You can do that None stuff or whatever at this point, if you don't like exceptions.
我知道通常在python中,列表推导式是首选或至少 这是我读到的,但老实说,我不认为有什么问题。当然,Python不是FP语言,但是Map / Reduce / Filter是完全可读的,并且是函数式编程中最标准的标准用例。< / p >

就是这样。了解函数式编程。

过滤条件列表

没有比这更简单的了:

next(filter(lambda x: x.val == value,  my_unfiltered_list)) # Optionally: next(..., None) or some other default value to prevent Exceptions
你也可以通过__eq__方法为你的Test类实现丰富的比较,并使用in操作符。 不确定这是否是最好的独立方式,但如果你需要比较基于其他地方的valueTest实例,这可能是有用的
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"

对于下面的代码,xGen是一个匿名生成器表达式,yFilt是一个过滤器对象。注意,对于xGen,当列表耗尽时,返回额外的None参数,而不是抛出StopIteration。

arr =((10,0), (11,1), (12,2), (13,2), (14,3))


value = 2
xGen = (x for x in arr if x[1] == value)
yFilt = filter(lambda x: x[1] == value, arr)
print(type(xGen))
print(type(yFilt))


for i in range(1,4):
print('xGen: pass=',i,' result=',next(xGen,None))
print('yFilt: pass=',i,' result=',next(yFilt))

输出:

<class 'generator'>
<class 'filter'>
xGen: pass= 1  result= (12, 2)
yFilt: pass= 1  result= (12, 2)
xGen: pass= 2  result= (13, 2)
yFilt: pass= 2  result= (13, 2)
xGen: pass= 3  result= None
Traceback (most recent call last):
File "test.py", line 12, in <module>
print('yFilt: pass=',i,' result=',next(yFilt))
StopIteration

你可以这样做

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


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

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

< p > 一个简单的例子: 我们有如下数组

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

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

  1. 使用带有列表理解的方法next
next(x for x in li if x["id"] == 1 )
  1. 使用列表推导式并返回第一项
[x for x in li if x["id"] == 1 ][0]
  1. 自定义函数
def find(arr , id):
for x in arr:
if x["id"] == id:
return x
find(li , 1)

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

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

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

如果你在Python中寻找数组中的对象。你可以使用if条件句。

 model_t1 = [0,1,2,3,4]
model_t2 = [7,8,9,15,14]
_data = model_t1


for md in model_t2:
_data.append(md)


for p_data in _data:
if len(p_data['Property']) == 'Value':
print(json(p_data))