J'ai une liste de booléens:
[True, True, False, False, False, True]
et je cherche un moyen de compter le nombre de True
dans la liste (donc dans l'exemple ci-dessus, je veux que le retour soit 3
.) J'ai trouvé des exemples de recherche du nombre d'occurrences d'éléments spécifiques, mais y a-t-il plus moyen efficace de le faire puisque je travaille avec des booléens? Je pense à quelque chose d'analogue à all
ou any
.
Réponses:
True
est égal à1
.la source
issubclass(bool, int)
tient en fait, donc il n'y a pas de coercition.list
a unecount
méthode:C'est en fait plus efficace que
sum
, en plus d'être plus explicite sur l'intention, il n'y a donc aucune raison d'utilisersum
:la source
sum
l'autre réponse si vous avez d'autres valeurs «vraies» que 1 ou Vrai non plus. D'ailleurs, alors la question ne mentionnait rien d'autre queTrue
ouFalse
.Si vous ne vous préoccupez que de la constante
True
, un simple suffitsum
. Cependant, gardez à l'esprit qu'en Python, d'autres valeurs sont également évaluéesTrue
. Une solution plus robuste serait d'utiliser la fonctionbool
intégrée:MISE À JOUR: Voici une autre solution tout aussi robuste qui a l'avantage d'être plus transparente:
Anecdotes sur PS Python: cela
True
pourrait être vrai sans être 1. Attention: n'essayez pas cela au travail!Beaucoup plus de mal:
la source
if
déclaration) est plus compliqué que de simplement testerTrue
. Voir docs.python.org/py3k/library/stdtypes.html#truth . LeTrue = 2
était juste de renforcer le concept de « vrai » est plus complexe; avec un peu de code supplémentaire (c'est-à-dire en utilisantbool()
), vous pouvez rendre la solution plus robuste et plus générale.True
etFalse
sont des mots-clés et vous ne pouvez pas les changer.Vous pouvez utiliser
sum()
:la source
Juste pour être complet (
sum
c'est généralement préférable), je voulais mentionner que nous pouvons également utiliserfilter
pour obtenir les valeurs de vérité. Dans le cas habituel,filter
accepte une fonction comme premier argument, mais si vous la transmettezNone
, elle filtrera toutes les valeurs «de vérité». Cette fonctionnalité est quelque peu surprenante, mais elle est bien documentée et fonctionne à la fois en Python 2 et 3.La différence entre les versions, c'est qu'en Python 2
filter
retourne une liste, nous pouvons donc utiliserlen
:Mais dans Python 3,
filter
retourne un itérateur, donc nous ne pouvons pas utiliserlen
, et si nous voulons éviter d'utilisersum
(pour une raison quelconque), nous devons recourir à la conversion de l'itérateur en une liste (ce qui rend cela beaucoup moins joli):la source
Après avoir lu toutes les réponses et commentaires sur cette question, j'ai pensé faire une petite expérience.
J'ai généré 50 000 booléens aléatoires et ai appelé
sum
etcount
sur eux.Voici mes résultats:
Juste pour être sûr, je l'ai répété plusieurs fois:
Et comme vous pouvez le voir,
count
c'est 3 fois plus rapide quesum
. Je suggérerais donc d'utilisercount
comme je l'ai fait danscount_it
.Version Python: 3.6.7 Cœurs de
processeur: 4
Taille de RAM: 16 Go
OS: Ubuntu 18.04.1 LTS
la source
Il est plus sûr de passer en
bool
premier. Cela se fait facilement:Ensuite, vous attraperez tout ce que Python considère comme vrai ou faux dans le compartiment approprié:
Si vous préférez, vous pouvez utiliser une compréhension:
la source
Je préfère
len([b for b in boollist if b is True])
(ou l'équivalent de Generator-Expression), car c'est assez explicite. Moins «magique» que la réponse proposée par Ignacio Vazquez-Abrams.Vous pouvez également le faire, ce qui suppose toujours que bool est convertible en int, mais ne fait aucune hypothèse sur la valeur de True:
ntrue = sum(boollist) / int(True)
la source
if b
. Mais, plus important encore, vous construisez une liste jetable exigeant que toutes les valeurs soient en mémoire à la fois et que vous ne pouvez pas utiliserlen
avec une expression de générateur. Mieux vaut éviter de telles pratiques afin que la solution puisse évoluer.if b
est tout à fait faux. Ce ne serait correct que si la question portait sur les éléments évalués comme True, plutôt que sur les vrais booléens True. Je prends cependant votre deuxième point. Dans ce cas, il y a la variantesum(1 if b is True else 0 for b in boollist)
.sum(1 for b in boollist if b is True)