我有一个对象列表。我想在这个列表中找到一个(第一个或任何)对象,它的属性(或方法结果-无论什么)等于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()不会有任何区别,因为它仍然会遍历列表。
附:等式到值只是一个例子。当然,我们想要得到一个满足任何条件的元素。
举个简单的例子:
我们有下面的数组
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'}
你也可以通过你的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"
因为它没有被提及只是为了完成。
好的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是完全可读的,并且是函数式编程中最标准的标准用例。
就是这样。了解函数式编程。
过滤条件列表
没有比这更简单的了:
next(filter(lambda x: x.val == value, my_unfiltered_list)) # Optionally: next(..., None) or some other default value to prevent Exceptions
对于下面的代码,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