cin*_*nsk 66 python functional-programming list count sequence
假设我有一个包含大量项目的列表.
l = [ 1, 4, 6, 30, 2, ... ]
Run Code Online (Sandbox Code Playgroud)
我想从该列表中获取项目数,其中项目应满足特定条件.我的第一个想法是:
count = len([i for i in l if my_condition(l)])
Run Code Online (Sandbox Code Playgroud)
但是如果my_condition()过滤列表也有很多项,我认为为过滤结果创建新列表只是浪费内存.为了效率,恕我直言,以上呼叫不能比:
count = 0
for i in l:
if my_condition(l):
count += 1
Run Code Online (Sandbox Code Playgroud)
有没有任何功能风格的方法来获得满足特定条件的项目#而不生成临时列表?
提前致谢.
DSM*_*DSM 87
您可以使用生成器表达式:
>>> l = [1, 3, 7, 2, 6, 8, 10]
>>> sum(1 for i in l if i % 4 == 3)
2
Run Code Online (Sandbox Code Playgroud)
甚至
>>> sum(i % 4 == 3 for i in l)
2
Run Code Online (Sandbox Code Playgroud)
它使用的事实int(True) == 1.
或者,您可以使用itertools.imap(python 2)或简单地map(python 3):
>>> def my_condition(x):
... return x % 4 == 3
...
>>> sum(map(my_condition, l))
2
Run Code Online (Sandbox Code Playgroud)
Joh*_*hnJ 17
你想要一个生成器理解而不是列表.
例如,
l = [1, 4, 6, 7, 30, 2]
def my_condition(x):
return x > 5 and x < 20
print sum(1 for x in l if my_condition(x))
# -> 2
print sum(1 for x in range(1000000) if my_condition(x))
# -> 14
Run Code Online (Sandbox Code Playgroud)
或者使用itertools.imap(虽然我认为显式列表和生成器表达式看起来更像Pythonic).
请注意,虽然从sum示例中并不明显,但您可以很好地组合生成器理解.例如,
inputs = xrange(1000000) # In Python 3 and above, use range instead of xrange
odds = (x for x in inputs if x % 2) # Pick odd numbers
sq_inc = (x**2 + 1 for x in odds) # Square and add one
print sum(x/2 for x in sq_inc) # Actually evaluate each one
# -> 83333333333500000
Run Code Online (Sandbox Code Playgroud)
关于这种技术的一个很酷的事情是,你可以在代码中指定概念上独立的步骤,而不必在内存中强制评估和存储,直到评估最终结果.
你可以这样做:
l = [1,2,3,4,5,..]
count = sum(1 for i in l if my_condition(i))
Run Code Online (Sandbox Code Playgroud)
只为满足条件的每个元素添加1.
reduce如果您更喜欢函数式编程,也可以使用它
reduce(lambda count, i: count + my_condition(i), l, 0)
Run Code Online (Sandbox Code Playgroud)
这样,您只能执行1次传递,并且不会生成任何中间列表.