Mam listę wartości logicznych:
[True, True, False, False, False, True]
i szukam sposobu na policzenie liczby wystąpień True
na liście (więc w powyższym przykładzie chcę, aby był to zwrot 3
). Znalazłem przykłady szukania liczby wystąpień określonych elementów, ale czy jest więcej skuteczny sposób na zrobienie tego, ponieważ pracuję z Booleansami? Myślę o czymś analogicznym do all
lub any
.
Odpowiedzi:
True
jest równa1
.źródło
issubclass(bool, int)
faktycznie trzyma, więc nie ma przymusu.list
macount
metodę:W rzeczywistości jest to bardziej wydajne niż
sum
, a także bardziej wyraźne co do zamiaru, więc nie ma powodu, aby używaćsum
:źródło
sum
drugiej odpowiedzi, jeśli masz inne wartości „prawda” oprócz 1 lub Prawda. Poza tym w pytaniu nie było nic, aleTrue
lubFalse
.Jeśli interesuje Cię tylko stała
True
, prostesum
jest w porządku. Należy jednak pamiętać, że w Pythonie obliczaneTrue
są również inne wartości . Bardziej niezawodnym rozwiązaniem byłoby użyciebool
wbudowanego:AKTUALIZACJA: Oto inne równie solidne rozwiązanie, które ma tę zaletę, że jest bardziej przejrzyste:
PS Python ciekawostki:
True
może być prawdą bez bycia 1. Uwaga: nie próbuj tego w pracy!O wiele bardziej zła:
źródło
if
instrukcji) jest bardziej skomplikowany niż tylko testowanieTrue
. Zobacz docs.python.org/py3k/library/stdtypes.html#truth . MiałoTrue = 2
to tylko podkreślić, że pojęcie „prawdy” jest bardziej złożone; z odrobiną dodatkowego kodu (np. używającbool()
) możesz uczynić rozwiązanie bardziej niezawodnym i bardziej ogólnym.True
iFalse
są słowami kluczowymi i nie można ich zmienić.Możesz użyć
sum()
:źródło
Ze względu na kompletność (
sum
jest to zwykle preferowane), chciałem wspomnieć, że możemy również użyćfilter
do uzyskania prawdziwych wartości. W zwykłym przypadkufilter
przyjmuje funkcję jako pierwszy argument, ale jeśli ją przekażeszNone
, będzie filtrować pod kątem wszystkich „prawdziwych” wartości. Ta funkcja jest nieco zaskakująca, ale jest dobrze udokumentowana i działa zarówno w Pythonie 2, jak i 3.Różnica między wersjami polega na tym, że w Pythonie 2
filter
zwraca listę, więc możemy użyćlen
:Ale w Pythonie 3
filter
zwraca iterator, więc nie możemy go używaćlen
, a jeśli chcemy uniknąć używaniasum
(z jakiegokolwiek powodu), musimy uciec się do konwersji iteratora na listę (co czyni to znacznie mniej ładnym):źródło
Po przeczytaniu wszystkich odpowiedzi i komentarzy na to pytanie, pomyślałem, że zrobię mały eksperyment.
I generowane 50.000 losowe wartości logicznych i nazywa
sum
icount
na nich.Oto moje wyniki:
Dla pewności powtórzyłem to jeszcze kilka razy:
I jak widać,
count
jest 3 razy szybszy niżsum
. Więc proponuję użyćcount
tak, jak zrobiłem wcount_it
.Wersja Pythona: 3.6.7
Rdzenie procesora: 4
Pamięć RAM: 16 GB
System operacyjny: Ubuntu 18.04.1 LTS
źródło
Bezpieczniej jest
bool
najpierw przejść . Można to łatwo zrobić:Następnie złapiesz wszystko, co Python uzna za Prawda lub Fałsz, do odpowiedniego zasobnika:
Jeśli wolisz, możesz użyć zrozumienia:
źródło
Wolę
len([b for b in boollist if b is True])
(lub odpowiednik wyrażenia generatora), ponieważ jest to dość oczywiste. Mniej „magiczna” niż odpowiedź zaproponowana przez Ignacio Vazquez-Abrams.Alternatywnie możesz to zrobić, co nadal zakłada, że bool można zamienić na int, ale nie przyjmuje żadnych założeń dotyczących wartości True:
ntrue = sum(boollist) / int(True)
źródło
if b
. Ale, co ważniejsze, tworzysz listę jednorazową wymagającą, aby wszystkie wartości były jednocześnie w pamięci i nie możesz jej używaćlen
z wyrażeniem generatora. Lepiej unikać takich praktyk, aby można było skalować rozwiązanie.if b
jest dokładnie w błędzie. Byłoby poprawne tylko wtedy, gdyby pytanie dotyczyło elementów ocenianych jako Prawda, a nie rzeczywistych wartości logicznych True. Ale rozumiem twoją drugą kwestię. W takim razie jest wariantsum(1 if b is True else 0 for b in boollist)
.sum(1 for b in boollist if b is True)