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