Подсчет количества истинных булевых значений в списке Python


у меня есть список логических значений:

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

и я ищу способ, чтобы подсчитать количество True в списке (так что в примере выше, я хочу, чтобы возврат был 3.) Я нашел примеры поиска количества вхождений конкретных элементов, но есть ли более эффективный способ сделать это, так как я работаю с булевыми значениями? Я думаю о чем-то аналогичном all или any.

7 88

7 ответов:

True равна 1.

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

list есть count способ:

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

если вас интересует постоянная True, просто sum - это хорошо. Однако имейте в виду, что в Python другие значения оцениваются как True как хорошо. Более надежным решением было бы использовать bool builtin:

>>> 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 trivia: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

просто для полноты картины (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 считает истинным или ложным в соответствующее ведро:

>>> 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]) (или эквивалент генератора-выражения), так как это вполне объяснимо. Менее магической, чем ответ, предложенный Игнасио Васкес-Абрамс.

альтернативно, вы можете сделать это, что по-прежнему предполагает, что bool преобразуется в int, но не делает никаких предположений о значении True: ntrue = sum(boollist) / int(True)