我有一份布尔人名单:
[True, True, False, False, False, True]
我正在寻找一种方法来计算列表中True
的数量(所以在上面的示例中,我希望返回为3
。)我找到了寻找的示例特定元素的出现次数,但是因为我和布尔人一起工作,有没有更有效的方法呢?我正在考虑类似于all
或any
的内容。
答案 0 :(得分:157)
True
等于1
。
>>> sum([True, True, False, False, False, True])
3
答案 1 :(得分:101)
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)
答案 2 :(得分:38)
如果您只关注常量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
P.S。 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
答案 3 :(得分:6)
您可以使用sum()
:
>>> sum([True, True, False, False, False, True])
3
答案 4 :(得分:4)
只是为了完整'清酒(sum
通常更可取),我想提一下,我们也可以使用filter
来获得真正的价值。在通常情况下,filter
接受一个函数作为第一个参数,但如果你传递它None
,它将过滤所有" truthy"值。这个功能有点令人惊讶,但有很好的文档记录,适用于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
答案 5 :(得分:2)
首先运行bool
更安全。这很容易做到:
>>> sum(map(bool,[True, True, False, False, False, True]))
3
然后,您将把Python认为正确或错误的所有内容都捕获到相应的存储桶中:
>>> 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]
答案 6 :(得分:1)
我更喜欢len([b for b in boollist if b is True])
(或者相当于generator-expression),因为它非常不言自明。比Ignacio Vazquez-Abrams提出的答案更不“神奇”。
或者,你可以这样做,仍然假设bool可以转换为int,但不假设True的值:
ntrue = sum(boollist) / int(True)
答案 7 :(得分:1)
在阅读完有关该问题的所有答案和评论后,我想做一个小实验。
我生成了50,000个随机布尔值,并在它们上分别调用了def save_result
4.times do
@result = Result.create(res_params)
end
end
def testpage
@question = Question.find(params[:id])
@answers = @question.answers
@result = Result.new
end
def res_params
params.require(:result).permit(:user_id, :question_id, :answer_id, :isright)
end
和sum
。
这是我的结果:
count
可以肯定的是,我又重复了几次:
>>> 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
。
Python版本:3.6.7
CPU核心:4
RAM大小:16 GB
操作系统:Ubuntu 18.04.1 LTS