파이썬리스트에서 참 부울 수 계산


152

부울 목록이 있습니다.

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

그리고 True목록 의 수를 계산하는 방법을 찾고 있습니다 (위의 예에서는 return을 원합니다 3.) 특정 요소의 발생 횟수를 찾는 예를 찾았지만 더 많은 것이 있습니까? 부울로 작업하고 있기 때문에 효율적인 방법은 무엇입니까? 나는에 뭔가 비슷한 생각 해요 allany.


어셈블러 만 사용하여 하드웨어에서 비트 카운팅이 수행 된 방식을 기억하는 것처럼.
Vladislavs Dovgalecs

답변:


207

True와 같습니다 1.

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

23
그것은 관용적이지 않으며 bool의 유형 강제의 "학대"를 만듭니다.
Jan Segre

24
@ Jan Segre, 강제는 없으며 bool은 정수 유형입니다.
panda-34

25
@ panda-34, 나는 확인하고 issubclass(bool, int)실제로 유지하므로 강압은 없습니다.
Jan Segre

153

listcount방법을 :

>>> [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
0 값이 있으면 False 값을 계산할 수 없습니다
Kostanos

10
sum1 또는 True 이외의 다른 "true"값이있는 경우 다른 답변을 사용할 수 없습니다 . 게다가 질문에는 True또는 이외의 언급이 없었습니다 False.
Mark Tolonen

43

상수에만 관심이 있다면 True간단 sum합니다. 그러나 파이썬에서는 다른 값들도 평가된다는 것을 명심하십시오 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 trivia : 1이 아닌 사실 일 True 있습니다. 경고 : 직장에서 시도하지 마십시오!

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

좋아, 나는 당신의 모범을 보았습니다. 그것의 LOL-ness와는 별도로, 실제로 여기에 표시된 것을 수행해야 할 이유가 있습니까?
acs

1
그렇습니다. 내가 지적했듯이, "true"에 대한 파이썬 테스트는 ( if문 에서처럼 ) 단순히 테스트하는 것보다 더 복잡합니다 True. docs.python.org/py3k/library/stdtypes.html#truth를 참조하십시오 . 는 True = 2"진실"의 개념이 더 복잡 있음을 강화하기 위해 단지 있었다; 약간의 추가 코드 (예 :)를 사용 bool()하면 솔루션을보다 강력하고 일반적으로 만들 수 있습니다.
Ned Deily

9
파이썬 3에서, True그리고 False키워드는 당신이 그들을 변경할 수 없습니다.
ThePiercingPrince

8

당신은 사용할 수 있습니다 sum():

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

5

완전성을 위해서 ( 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

그러나 파이썬 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

4

이 질문에 대한 모든 답변과 의견을 읽은 후 작은 실험을 생각했습니다.

나는 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보다 시피, 보다 3 배 빠릅니다 sum. 그래서 내가 count했던 것처럼 사용하는 것이 좋습니다 count_it.

파이썬 버전 : 3.6.7
CPU 코어 : 4
RAM 크기 : 16 GB
OS : 우분투 18.04.1 LTS


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]

1

나는 len([b for b in boollist if b is True])매우 자명하기 때문에 선호합니다 (또는 생성기 표현과 동등한 것). Ignacio Vazquez-Abrams가 제안한 답변보다 덜 '마 법적'입니다.

또는 bool을 int로 변환 할 수 있다고 가정하지만 True의 값에 대해서는 가정하지 않습니다. ntrue = sum(boollist) / int(True)


솔루션에 최소한 두 가지 문제가 있습니다. 첫째, 동일한 견고성 문제를 겪고 있습니다. 테스트를로 변경하여 해결할 수 if b있습니다. 그러나 더 중요한 것은 모든 값을 한 번에 메모리에 저장해야하는 폐기 목록을 len생성하고 생성기 식과 함께 사용할 수 없다는 것 입니다. 솔루션을 확장 할 수 있도록 이러한 관행을 피하는 것이 좋습니다.
Ned Deily

@ Ned Deily : if b정확히 잘못되었습니다. 실제 True 부울이 아닌 True로 평가되는 항목에 대한 질문 인 경우에만 정확합니다. 나는 당신의 두 번째 요점을 취합니다. 이 경우 변형이 sum(1 if b is True else 0 for b in boollist)있습니다.
kampu

다른 곳에서 언급했듯이 OP가 실제로 bool 유형의 개체 만 값 1로 계산하는지 또는 참으로 평가되는 더 크고 일반적으로 더 유용한 값 집합을 의미하는지 여부는 분명하지 않습니다. 전자의 경우, 신원 테스트가 올바른 접근 방법이지만 제한적입니다. bool 유형의 객체는 어쨌든 파이썬에서 다소 이상한 오리이며 비교적 최근에 언어에 추가되었습니다. 어쨌든 나는 더 간단하게 갈 것이다.sum(1 for b in boollist if b is True)
Ned Deily
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.