python:从列表(序列)中获取具有一定条件的项目数
假设我有一个包含大量项目的列表。
l = [ 1, 4, 6, 30, 2, ... ]
我想从列表中获取项目的数量,其中项目应该满足某些条件。 我的第一个想法是:
count = len([i for i in l if my_condition(l)])
但是,如果my_condition()过滤列表也有很多项目,我认为创build新的过滤结果列表只是浪费内存。 为了效率,恕我直言,上述呼叫不能比:
count = 0 for i in l: if my_condition(l): count += 1
是否有任何function风格的方式来获得满足一定条件的项目#而不生成临时列表?
提前致谢。
你可以使用一个生成器expression式 :
>>> l = [1, 3, 7, 2, 6, 8, 10] >>> sum(1 for i in l if i % 4 == 3) 2
甚至
>>> sum(i % 4 == 3 for i in l) 2
它使用int(True) == 1
的事实。
另外,你可以使用itertools.imap
(python 2)或者简单的map
(python 3):
>>> def my_condition(x): ... return x % 4 == 3 ... >>> sum(map(my_condition, l)) 2
你需要一个生成器理解而不是列表。
例如,
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
或者使用itertools.imap
(尽pipe我认为显式列表和生成器expression式看起来更像Pythonic)。
请注意,尽pipe从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
关于这种技术的一个很酷的事情是,你可以在代码中指定概念上单独的步骤,而不必强制评估和存储在内存中,直到最终结果被评估。
你可以做这样的事情:
l = [1,2,3,4,5,..] count = sum(1 for i in l if my_condition(i))
对于满足条件的每个元素只增加1。
如果你喜欢function性编程,也可以使用reduce
来完成
reduce(lambda count, i: count + my_condition(i), l, 0)
这样你只做1次,没有中间列表生成。
from itertools import imap sum(imap(my_condition, l))
我有类似的问题,并通过使用生成器来解决它。
我也认为这个问题可以帮助你: 列表过滤:列表理解与lambda +filter