1

所以我有一个数组,比如说[5,2,2,0],是否有一个函数可以返回通过标准的元素数量?

目前我正在这样做:

a = [5,2,2,0]
len([i for i in a if i > 0])

也有人提出了这种方法:

sum(b > 0 for b in a)

但 IMO 这真的是一回事,只是可读性差了一点。

有没有这样的方法我可以使用:

def crit(x): return x > 0
a.count(criterion=crit)
4

3 回答 3

4

你能做的不多,但如果你已经有了你的谓词

def crit(x):
   return x > 0

你可以做

sum(map(crit, a))

或者

len(filter(crit, a))

 

len([x for x in a if x > 0])是最有效的,但如果您想重用谓词,可能会导致代码重复。

测试:

In [6]: %timeit len([x for x in a if x > 0])
100000 loops, best of 3: 3.57 us per loop

In [7]: def crit(x):
   ...:     return x > 0
   ...:

In [8]: %timeit len([x for x in a if crit(x)])
100000 loops, best of 3: 10.1 us per loop

In [9]: %timeit sum([x > 0 for x in a])
100000 loops, best of 3: 5.66 us per loop

In [10]: %timeit sum([crit(x) for x in a])
100000 loops, best of 3: 12 us per loop

In [11]: %timeit sum(map(crit, a))
100000 loops, best of 3: 11.3 us per loop

In [12]: %timeit len(filter(crit, a))
100000 loops, best of 3: 8.21 us per loop

生成器(生成器没有len):

In [13]: %timeit sum(1 for x in a if x > 0)
100000 loops, best of 3: 3.99 us per loop

In [14]: %timeit sum([1 for x in a if crit(x)])
10000 loops, best of 3: 10.6 us per loop

In [15]: %timeit sum(x > 0 for x in a)
100000 loops, best of 3: 6.24 us per loop

In [16]: %timeit sum(crit(x) for x in a)
100000 loops, best of 3: 13 us per loop

imapmap

In [17]: %timeit sum(itertools.imap(crit, a))
100000 loops, best of 3: 10.7 us per loop

 

在测试了所有这些之后,我想我会选择 [13]、[17] 或 [14]。

于 2013-02-06T16:11:12.277 回答
2

我会采用这种sum方法而不是具体化一个列表 - 如果你觉得它太可怕了,只需编写一个辅助函数:

def count_if(f, iterable):
    return sum(1 for i in iterable if f(i))

或者更好的是,使用itertools 文档中的一种方法:

def quantify(iterable, pred=bool):
    "Count how many times the predicate is true"
    return sum(imap(pred, iterable))
于 2013-02-06T16:13:30.723 回答
1

你可以使用filter函数len(filter(crit, a))

于 2013-02-06T16:11:50.717 回答