J'essaie de comprendre comment les fonctions intégrées any()
et all()
Python fonctionnent.
J'essaie de comparer les tuples de sorte que si une valeur est différente, elle reviendra True
et si elles sont toutes identiques, elle reviendra False
. Comment travaillent-ils dans ce cas pour revenir [Faux, Faux, Faux]?
d
est un defaultdict(list)
.
print d['Drd2']
# [[1, 5, 0], [1, 6, 0]]
print list(zip(*d['Drd2']))
# [(1, 1), (5, 6), (0, 0)]
print [any(x) and not all(x) for x in zip(*d['Drd2'])]
# [False, False, False]
À ma connaissance, cela devrait produire
# [False, True, False]
puisque (1,1) sont identiques, (5,6) sont différents et (0,0) sont identiques.
Pourquoi est-il évalué à False pour tous les tuples?
Réponses:
Vous pouvez approximativement penser à
any
etall
comme une série d' opérateurs logiquesor
etand
, respectivement.tout
any
reviendraTrue
quand au moins un des éléments est Truthy. Lisez à propos de Truth Value Testing.tout
all
ne reviendraTrue
que lorsque tous les éléments seront vrais.Table de vérité
Remarque 1: le cas itérable vide est expliqué dans la documentation officielle, comme ceci
any
Puisqu'aucun des éléments n'est vrai, il revient
False
dans ce cas.all
Puisqu'aucun des éléments n'est faux, il revient
True
dans ce cas.Note 2:
Une autre chose importante à savoir
any
etall
c'est qu'elle court-circuitera l'exécution, au moment où ils connaîtront le résultat. L'avantage est qu'il n'est pas nécessaire de consommer l'intégralité de l'itére. Par exemple,Ici,
(not (i % 6) for i in range(1, 10))
est une expression de générateur qui retourneTrue
si le nombre actuel entre 1 et 9 est un multiple de 6.any
itère lemultiples_of_6
et quand il se rencontre6
, il trouve une valeur Truthy, donc il revient immédiatementTrue
, et le reste dumultiples_of_6
n'est pas itéré. Voilà ce que nous voyons quand nous imprimonslist(multiples_of_6)
, le résultat de7
,8
et9
.Cette excellente chose est utilisée très intelligemment dans cette réponse .
Avec cette compréhension de base, si nous regardons votre code, vous faites
ce qui garantit qu'au moins une des valeurs est Truthy mais pas toutes. C'est pourquoi il revient
[False, False, False]
. Si vous vouliez vraiment vérifier si les deux nombres ne sont pas identiques,la source
bool(data) and all(...)
devrait marcher.any
etall
prendre des itérables et retournerTrue
si l'un et tous (respectivement) des éléments le sontTrue
.Si les itérables sont vides,
any
renvoieFalse
etall
retourneTrue
.Je manifestais
all
etany
pour les étudiants en classe aujourd'hui. Ils étaient surtout confus au sujet des valeurs de retour pour les itérables vides. En l'expliquant de cette façon, de nombreuses ampoules se sont allumées.Comportement de raccourci
Ils,
any
etall
, à la fois regard d'une condition qui leur permet d'arrêter l' évaluation. Les premiers exemples que j'ai donnés les ont obligés à évaluer le booléen pour chaque élément de la liste entière.(Notez que le littéral de liste n'est pas lui-même évalué paresseusement - vous pouvez l'obtenir avec un itérateur - mais cela est juste à des fins d'illustration.)
Voici une implémentation Python de tout et de tout:
Bien sûr, les implémentations réelles sont écrites en C et sont beaucoup plus performantes, mais vous pouvez remplacer ce qui précède et obtenir les mêmes résultats pour le code dans cette réponse (ou toute autre).
all
all
vérifie que les éléments doivent êtreFalse
(afin qu'il puisse revenirFalse
), puis il retourneTrue
si aucun d'entre eux ne l'étaitFalse
.any
La façon dont cela
any
fonctionne est qu'il vérifie que les éléments doivent êtreTrue
(afin qu'il puisse retournerTrue), then it returns
Falseif none of them were
True`.Je pense que si vous gardez à l'esprit le comportement de raccourci, vous comprendrez intuitivement comment ils fonctionnent sans avoir à référencer une table de vérité.
Preuve
all
etany
raccourci:Créez d'abord un noisy_iterator:
et maintenant, parcourons les listes bruyamment, en utilisant nos exemples:
Nous pouvons voir des
all
arrêts sur la première fausse vérification booléenne.Et
any
s'arrête sur la première vérification booléenne True:La source
Regardons la source pour confirmer ce qui précède.
Voici la source de
any
:Et voici la source de
all
:la source
Python/bltinmodule.c
- je l'ai ajouté à ce qui précède.Je sais que c'est vieux, mais j'ai pensé qu'il pourrait être utile de montrer à quoi ressemblent ces fonctions dans le code. Cela illustre vraiment la logique, mieux que du texte ou un tableau IMO. En réalité, ils sont implémentés en C plutôt qu'en Python pur, mais ceux-ci sont équivalents.
En particulier, vous pouvez voir que le résultat pour les itérables vides est juste le résultat naturel, pas un cas spécial. Vous pouvez également voir le comportement de court-circuit; ce serait en fait plus de travail pour qu'il n'y ait pas de court-circuit.
Lorsque Guido van Rossum (le créateur de Python) a proposé pour la première fois d'ajouter
any()
etall()
, il les a expliqués en affichant exactement les extraits de code ci-dessus.la source
Le code en question que vous demandez provient de ma réponse donnée ici . Il était destiné à résoudre le problème de la comparaison de plusieurs tableaux de bits - c'est-à-dire des collections de
1
et0
.any
etall
sont utiles lorsque vous pouvez compter sur la «véracité» des valeurs - c'est-à-dire leur valeur dans un contexte booléen. 1 estTrue
et 0 estFalse
, une commodité dont cette réponse a tiré parti. 5 se trouve être aussiTrue
, donc quand vous mélangez cela dans vos entrées possibles ... eh bien. Ça ne marche pas.Vous pouvez plutôt faire quelque chose comme ceci:
Il manque l'esthétique de la réponse précédente (j'ai vraiment aimé le look de
any(x) and not all(x)
), mais il fait le travail.la source
True
quand les valeurs sont différentes, la longueur de l'ensemble devrait être de 2, pas de 1.la source
la source
Le concept est simple:
la source
la source