4 votes

Problème avec la syntaxe "any" de python

J'ai un problème avec la syntaxe "any". J'ai deux listes.

mainseq=["hali","hulu","habi"]
seq=["a","b","c","d"]

Je veux savoir si les éléments de seq existent dans mainseq.

for each in seq:
    if any(each in halum for halum in mainseq):
        print each

Cela me donne "a" et "b" comme prévu. Mais lorsque je supprime la syntaxe "any", j'obtiens toutes les valeurs dans seq, même si "c" et "d" ne figurent pas dans mainseq.

for each in seq:
    if (each in halum for halum in mainseq):
        print each

Que se passe-t-il dans les coulisses avec et SANS la fonction "any" ? Merci de m'aider.

3voto

MSeifert Points 6307

Pour comprendre ce qui se passe, vous pouvez le déboguer en imprimant une compréhension de liste équivalente et la commande boolean représentation et any :

for each in seq:
    print(each)
    print([each in halum for halum in mainseq])
    print(any(each in halum for halum in mainseq))
    print(bool(each in halum for halum in mainseq)) 

# a
# [True, False, True] <- contains more than one True element
# True                <- so any returns True
# True                <- boolean expression of a generator is always True

# b
# [False, False, True] <- contains one True element
# True                 <- so any returns True
# True                 <- boolean expression of a generator is always True

# c
# [False, False, False] <- no element is True
# False                 <- so any returns False
# True                  <- boolean expression of a generator is always True

# d
# [False, False, False] <- no element is True
# False                 <- so any returns False
# True                  <- boolean expression of a generator is always True

Mais n'oubliez pas qu'un générateur évaluera toujours True car un générateur n'a pas de explicite et n'a pas de représentation booléenne. longueur (voir Contrôle de la valeur de vérité dans la documentation officielle ).

any d'autre part, consomme le générateur et renvoie True seulement si tous est True . C'est le cas pour each == a et each == b . Ainsi, le if ne sera pas toujours déclenchée.

2voto

DhruvPathak Points 16181

Any renvoie une valeur booléenne True ou False.

Votre déclaration (each in halum for halum in mainseq) renvoie un générateur qui évalue une valeur vraie, ce qui fait que le code tombe toujours dans le bloc if. Voici un code plus verbeux qui explique cela :

http://ideone.com/AQ7dRs

mainseq=["hali","hulu","habi"]
seq=["a","b","c","d"]

print('Demo of any:\n')
for each in seq:
    boolFlag = any(each in halum for halum in mainseq)
    print('Any returned:{0}'.format(boolFlag)) 
    if boolFlag:
        print each

print('Demo of generator as truthy value:\n')

for each in seq:
    boolFlag = (each in halum for halum in mainseq)
    print('boolFlag is:{0}'.format(boolFlag))
    if boolFlag:
        print each
        print('{0} is Truthy'.format(boolFlag))

Sorties :

Any returned:True
a
Any returned:True
b
Any returned:False
Any returned:False
Demo of generator as truthy value:

boolFlag is:<generator object <genexpr> at 0xb7272bbc>
a
<generator object <genexpr> at 0xb7272bbc> is Truthy
boolFlag is:<generator object <genexpr> at 0xb7272be4>
b
<generator object <genexpr> at 0xb7272be4> is Truthy
boolFlag is:<generator object <genexpr> at 0xb7272bbc>
c
<generator object <genexpr> at 0xb7272bbc> is Truthy
boolFlag is:<generator object <genexpr> at 0xb7272be4>
d
<generator object <genexpr> at 0xb7272be4> is Truthy

1voto

Boregore Points 69

Any retourne vrai si la liste donnée contient au moins 1 élément. Vous pouvez obtenir ce que vous voulez en faisant ceci à la place :

for each in seq:
    for halum in mainseq:
        if each in halum:
            print each

1voto

zondo Points 11370

(each in halum for halum in mainseq) est un expression du générateur . Une expression génératrice est une valeur de vérité . L'utilisation de cette méthode dans le cadre d'un if sera toujours True afin que la suite soit toujours exécutée. any() recherche dans un itérable toute valeur qui est vraie. Par conséquent, son utilisation n'exécutera la suite que si l'un des résultats de l'expression du générateur est True .

1voto

Denis Kanygin Points 194

Any() renvoie True si un élément de l'itérable est true. Si la table itérative est vide, elle renvoie False.

Donc if any(each in halum for halum in mainseq): regarde les éléments à l'intérieur. Les itérations où chaque élément est "a" ou "b" contiennent ces éléments et donc l'énoncé if est vrai. Pour les cas "c" et "d", l'itérable est vide, ce qui produit false.

Lorsque vous supprimez any(), vous ne regardez plus à l'intérieur de l'itérable, mais vous demandez simplement si l'itérable lui-même n'est pas vrai.

if (each in halum for halum in mainseq) :

sera toujours vrai puisqu'il produira toujours un objet générateur valide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X