182

我有一个布尔值列表:

[True, True, False, False, False, True]

我正在寻找一种方法来计算True列表中的数量(因此在上面的示例中,我希望返回为3。)我找到了查找特定元素出现次数的示例,但是还有更多自从我使用布尔值以来,有效的方法是什么?我在想类似于allor的东西any

4

8 回答 8

249

True等于1

>>> sum([True, True, False, False, False, True])
3
于 2012-10-07T03:13:56.973 回答
196

list有一个count方法:

>>> [True,True,False].count(True)
2

这实际上比 更有效sum,并且对意图更明确,因此没有理由使用sum

In [1]: import random

In [2]: x = [random.choice([True, False]) for i in range(100)]

In [3]: %timeit x.count(True)
970 ns ± 41.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %timeit sum(x)
1.72 µs ± 161 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
于 2012-10-07T06:57:39.083 回答
47

如果您只关心常量True,那么简单sum就可以了。但是,请记住,在 Python 中,其他值True也会计算。更强大的解决方案是使用bool内置:

>>> l = [1, 2, True, False]
>>> sum(bool(x) for x in l)
3

更新:这是另一个同样强大的解决方案,具有更透明的优势:

>>> sum(1 for x in l if x)
3

PS Python琐事:True 可能不是1。警告:不要在工作中尝试这个!

>>> True = 2
>>> if True: print('true')
... 
true
>>> l = [True, True, False, True]
>>> sum(l)
6
>>> sum(bool(x) for x in l)
3
>>> sum(1 for x in l if x)
3

更邪恶:

True = False
于 2012-10-07T03:56:50.573 回答
8

您可以使用sum()

>>> sum([True, True, False, False, False, True])
3
于 2012-10-07T03:14:16.643 回答
6

在阅读了关于这个问题的所有答案和评论后,我想做一个小实验。

我生成了 50,000 个随机布尔值并调用sumcount它们。

这是我的结果:

>>> a = [bool(random.getrandbits(1)) for x in range(50000)]
>>> len(a)
50000
>>> a.count(False)
24884
>>> a.count(True)
25116
>>> def count_it(a):
...   curr = time.time()
...   counting = a.count(True)
...   print("Count it = " + str(time.time() - curr))
...   return counting
... 
>>> def sum_it(a):
...   curr = time.time()
...   counting = sum(a)
...   print("Sum it = " + str(time.time() - curr))
...   return counting
... 
>>> count_it(a)
Count it = 0.00121307373046875
25015
>>> sum_it(a)
Sum it = 0.004102230072021484
25015

为了确定,我又重复了几次:

>>> count_it(a)
Count it = 0.0013530254364013672
25015
>>> count_it(a)
Count it = 0.0014507770538330078
25015
>>> count_it(a)
Count it = 0.0013344287872314453
25015
>>> sum_it(a)
Sum it = 0.003480195999145508
25015
>>> sum_it(a)
Sum it = 0.0035257339477539062
25015
>>> sum_it(a)
Sum it = 0.003350496292114258
25015
>>> sum_it(a)
Sum it = 0.003744363784790039
25015

如您所见,count比 快 3 倍sum。所以我建议count像我在count_it.

Python 版本:3.6.7
CPU 内核:4
RAM 大小:16 GB
操作系统:Ubuntu 18.04.1 LTS

于 2018-12-12T14:06:46.383 回答
5

只是为了完整起见(sum通常更可取),我想提一下,我们也可以使用它filter来获取真实值。在通常情况下,filter接受一个函数作为第一个参数,但如果你传递它None,它将过滤所有“真实”值。这个特性有点令人惊讶,但是有很好的文档记录并且在 Python 2 和 3 中都可以使用。

版本之间的区别在于,在 Python 2 中filter返回一个列表,因此我们可以使用len

>>> bool_list = [True, True, False, False, False, True]
>>> filter(None, bool_list)
[True, True, True]
>>> len(filter(None, bool_list))
3

但是在 Python 3 中,filter返回一个迭代器,所以我们不能使用len,如果我们想避免使用sum(出于任何原因),我们需要将迭代器转换为一个列表(这使得这变得不那么漂亮了):

>>> bool_list = [True, True, False, False, False, True]
>>> filter(None, bool_list)
<builtins.filter at 0x7f64feba5710>
>>> list(filter(None, bool_list))
[True, True, True]
>>> len(list(filter(None, bool_list)))
3
于 2016-03-14T18:31:48.380 回答
3

先跑过去比较安全bool。这很容易做到:

>>> sum(map(bool,[True, True, False, False, False, True]))
3

然后,您会将 Python 认为是 True 或 False 的所有内容捕获到适当的存储桶中:

>>> allTrue=[True, not False, True+1,'0', ' ', 1, [0], {0:0}, set([0])]
>>> list(map(bool,allTrue))
[True, True, True, True, True, True, True, True, True]

如果您愿意,可以使用推导式:

>>> allFalse=['',[],{},False,0,set(),(), not True, True-1]
>>> [bool(i) for i in allFalse]
[False, False, False, False, False, False, False, False, False]
于 2012-10-08T20:38:16.683 回答
1

我更喜欢len([b for b in boollist if b is True])(或生成器表达式等价物),因为它是不言自明的。没有 Ignacio Vazquez-Abrams 提出的答案那么“神奇”。

或者,您可以这样做,它仍然假设 bool 可转换为 int,但不对 True 的值做任何假设: ntrue = sum(boollist) / int(True)

于 2012-10-07T04:22:57.463 回答