![](/img/trans.png)
[英]Count the number of True booleans grouped together between False booleans and return in list
[英]Counting the number of True Booleans in a Python List
我有一個布爾列表:
[True, True, False, False, False, True]
我正在尋找一種方法來計算列表中True
的數量(因此在上面的示例中,我希望返回值為3
。)我找到了尋找特定元素出現次數的示例,但是有因為我正在使用布爾值,所以有更有效的方法嗎? 我正在考慮類似於all
或any
的東西。
True
等於1
。
>>> sum([True, True, False, False, False, True])
3
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)
如果您只關心常量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
您可以使用sum()
:
>>> sum([True, True, False, False, False, True])
3
看完這個問題的所有答案和評論后,我想做一個小實驗。
我生成了 50,000 個隨機布爾值並調用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
比sum
快 3 倍。 所以我建議像我在count_it
所做的那樣使用count
。
Python版本:3.6.7
CPU核心:4
內存大小:16 GB
操作系統:Ubuntu 18.04.1 LTS
為了完整起見( 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
首先通過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]
我更喜歡len([b for b in boollist if b is True])
(或等效的生成器表達式),因為它是不言自明的。 比 Ignacio Vazquez-Abrams 提出的答案更“神奇”。
或者,您可以這樣做,它仍然假設 bool 可轉換為 int,但不對 True 的值做任何假設: ntrue = sum(boollist) / int(True)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.