2016-12-16 53 views
5

想象一下,你需要计算iterable元素的数量,以满足一些criteria - 是否有一个更好看的方式来做到这一点? 当然是python3。但2也很好。 我找不到合适的collectionsitertools python模块或内置程序。python的len的快捷方式(列表(过滤器(lambda x:criteria,iterable)))

+6

也许''总和(标准(X)在迭代X)'',假设该标准()仅返回适当的布尔值。 – jasonharper

+0

@jasonharper其实你的答案我最喜欢的 - 'sum(x <10和True for x in iterable)'超级方便:) – scythargon

回答

3

itertoolsrecipes尝试quantify配方:

def quantify(iterable, pred=bool): 
    "Count how many times the predicate is true" 
    return sum(map(pred, iterable)) 

more_itertools已经实现了这个配方,所以它的设计更加紧凑:

>>> import more_itertools as mit 

>>> iterable = [True, False, True, True] 
>>> mit.quantify(iterable) 
3 

对于比较:

>>> #len(list(filter(lambda x: criteria, iterable))) 
>>> len(list(filter(lambda x: x is True, iterable))) 
3 

性能

# A: len(list(filter(lambda x: criteria, iterable))) 
>>> %timeit -n 1000000 len(list(filter(lambda i: i is True, iterable))) 
1000000 loops, best of 3: 2.48 µs per loop 

# B: quantify(iterable, pred=condition) 
>>> %timeit -n 1000000 mit.quantify(iterable) 
1000000 loops, best of 3: 1.87 µs per loop 

# C: ilen(item for item in iterable if condition) 
>>> %timeit -n 1000000 mit.ilen(i for i in iterable if i is True) 
1000000 loops, best of 3: 5.27 µs per loop 

# D: len([item for item in iterable if condition]) 
>>> %timeit -n 1000000 len([i for i in iterable if i is True]) 
1000000 loops, best of 3: 973 ns per loop 

# E: sum(1 for _ in iterable if condition) 
>>> %timeit -n 1000000 sum(1 for i in iterable if i is True) 
1000000 loops, best of 3: 1.34 µs per loop 
  • 一个控制 - 作者的例子
  • 更快 - quantifyitertools配方
  • Ç最慢 - 发电机表达,使用more_itertools.ilen评估
  • d最快 - 列表理解
  • è更快 - 发电机表达,sum(1 for _ in ...)成语

虽然more_itertools.quantify简洁,独特的生成器表达式即使不是更快,也是平等的。然而,经典的列表解析(由@宏杰李首先提出)是表现最好的。

另请参阅将len()扩展到发电机的thread

1

列表解析提供了一种简洁的方式来创建列表。通用 应用程序将创建新列表,其中每个元素是 的一些操作的结果,该操作应用于另一个序列的每个成员或可迭代的 ,或者创建满足 特定条件的那些元素的子序列。

>>> squares = [] 
>>> for x in range(10): 
...  squares.append(x**2) 
... 
>>> squares 
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

注意,这将创建(或覆盖)一个变量名为x循环完成后仍然存在 。我们可以通过计算平方 名单无任何毒副作用:

squares = list(map(lambda x: x**2, range(10))) 

或等价:

squares = [x**2 for x in range(10)] 

不仅仅是把你放在了conditon如果statment这样

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] 
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)] 

你有符合条件的元素列表,你可以使用len(lsit_)计数元素

List Comprehension Document

+0

列表解析是Pythonic的路要走。好决定。 – pylang

+0

它在地球上如何回答这个问题? – scythargon

+0

@scythargon我更新了我的答案 –

3
sum(1 for i in A if condition(i))