[英]Counting the number of True Booleans in a Python List
I have a list of Booleans:我有一个布尔列表:
[True, True, False, False, False, True]
and I am looking for a way to count the number of True
in the list (so in the example above, I want the return to be 3
.) I have found examples of looking for the number of occurrences of specific elements, but is there a more efficient way to do it since I'm working with Booleans?我正在寻找一种方法来计算列表中
True
的数量(因此在上面的示例中,我希望返回值为3
。)我找到了寻找特定元素出现次数的示例,但是有因为我正在使用布尔值,所以有更有效的方法吗? I'm thinking of something analogous to all
or any
.我正在考虑类似于
all
或any
的东西。
True
is equal to 1
. True
等于1
。
>>> sum([True, True, False, False, False, True])
3
list
has a count
method: list
有一个count
方法:
>>> [True,True,False].count(True)
2
This is actually more efficient than sum
, as well as being more explicit about the intent, so there's no reason to use sum
:这实际上比
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)
If you are only concerned with the constant True
, a simple sum
is fine.如果您只关心常量
True
,那么简单的sum
就可以了。 However, keep in mind that in Python other values evaluate as True
as well.但是,请记住,在 Python 中,其他值也评估为
True
。 A more robust solution would be to use the bool
builtin:更强大的解决方案是使用
bool
内置:
>>> l = [1, 2, True, False]
>>> sum(bool(x) for x in l)
3
UPDATE: Here's another similarly robust solution that has the advantage of being more transparent:更新:这是另一个同样强大的解决方案,其优点是更加透明:
>>> sum(1 for x in l if x)
3
PS Python trivia: True
could be true without being 1. Warning: do not try this at work! 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
Much more evil:更邪恶:
True = False
You can use sum()
:您可以使用
sum()
:
>>> sum([True, True, False, False, False, True])
3
After reading all the answers and comments on this question, I thought to do a small experiment.看完这个问题的所有答案和评论后,我想做一个小实验。
I generated 50,000 random booleans and called sum
and count
on them.我生成了 50,000 个随机布尔值并调用
sum
并对它们进行count
。
Here are my results:这是我的结果:
>>> 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
Just to be sure, I repeated it several more times:可以肯定的是,我又重复了几次:
>>> 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
And as you can see, count
is 3 times faster than sum
.正如您所看到的,
count
比sum
快 3 倍。 So I would suggest to use count
as I did in count_it
.所以我建议像我在
count_it
所做的那样使用count
。
Python version: 3.6.7 Python版本:3.6.7
CPU cores: 4 CPU核心:4
RAM size: 16 GB内存大小:16 GB
OS: Ubuntu 18.04.1 LTS操作系统:Ubuntu 18.04.1 LTS
Just for completeness' sake ( sum
is usually preferable), I wanted to mention that we can also use filter
to get the truthy values.为了完整起见(
sum
通常更可取),我想提到我们也可以使用filter
来获取真实值。 In the usual case, filter
accepts a function as the first argument, but if you pass it None
, it will filter for all "truthy" values.在通常情况下,
filter
接受一个函数作为第一个参数,但如果你传递它None
,它将过滤所有“真实”值。 This feature is somewhat surprising, but is well documented and works in both Python 2 and 3.这个特性有点令人惊讶,但有很好的文档记录并且可以在 Python 2 和 3 中使用。
The difference between the versions, is that in Python 2 filter
returns a list, so we can use len
:版本之间的区别在于,在 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
But in Python 3, filter
returns an iterator, so we can't use len
, and if we want to avoid using sum
(for any reason) we need to resort to converting the iterator to a list (which makes this much less pretty):但是在 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
It is safer to run through bool
first.首先通过
bool
运行更安全。 This is easily done:这很容易做到:
>>> sum(map(bool,[True, True, False, False, False, True]))
3
Then you will catch everything that Python considers True or False into the appropriate bucket:然后,您将把 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]
If you prefer, you can use a comprehension:如果您愿意,可以使用理解式:
>>> allFalse=['',[],{},False,0,set(),(), not True, True-1]
>>> [bool(i) for i in allFalse]
[False, False, False, False, False, False, False, False, False]
I prefer len([b for b in boollist if b is True])
(or the generator-expression equivalent), as it's quite self-explanatory.我更喜欢
len([b for b in boollist if b is True])
(或等效的生成器表达式),因为它是不言自明的。 Less 'magical' than the answer proposed by Ignacio Vazquez-Abrams.比 Ignacio Vazquez-Abrams 提出的答案更“神奇”。
Alternatively, you can do this, which still assumes that bool is convertable to int, but makes no assumptions about the value of True: ntrue = sum(boollist) / int(True)
或者,您可以这样做,它仍然假设 bool 可转换为 int,但不对 True 的值做任何假设:
ntrue = sum(boollist) / int(True)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.