Question Pourquoi "not (True) in [False, True]" retourne False?


Si je fais ceci:

>>> False in [False, True]
True

Ça revient True. Simplement parce que False est dans la liste.

Mais si je le fais:

>>> not(True) in [False, True]
False

Ça revient False. Tandis que not(True) est égal à False:

>>> not(True)
False

Pourquoi?


457
2017-07-15 04:12


origine


Réponses:


Priorité de l'opérateur  2.x, 3.x. La préséance de not est inférieur à celui de in. Donc, c'est équivalent à:

>>> not (True in [False, True])
False

Voici ce que tu veux:

>>> (not True) in [False, True]
True

Comme le souligne @Ben: Il est recommandé de ne jamais écrire not(True), préférer not True. Le premier fait ressembler à un appel de fonction, tandis que not est un opérateur, pas une fonction.


705
2017-07-15 04:17



not x in y est évalué comme x not in y

Vous pouvez voir exactement ce qui se passe en démontant le code. Le premier cas fonctionne comme prévu:

>>> x = lambda: False in [False, True]
>>> dis.dis(x)
  1           0 LOAD_GLOBAL              0 (False)
              3 LOAD_GLOBAL              0 (False)
              6 LOAD_GLOBAL              1 (True)
              9 BUILD_LIST               2
             12 COMPARE_OP               6 (in)
             15 RETURN_VALUE

Le deuxième cas, évalue à True not in [False, True], lequel est False clairement:

>>> x = lambda: not(True) in [False, True]
>>> dis.dis(x)
  1           0 LOAD_GLOBAL              0 (True)
              3 LOAD_GLOBAL              1 (False)
              6 LOAD_GLOBAL              0 (True)
              9 BUILD_LIST               2
             12 COMPARE_OP               7 (not in)
             15 RETURN_VALUE        
>>> 

Ce que tu voulais exprimer à la place était (not(True)) in [False, True], ce qui est attendu Trueet vous pouvez voir pourquoi:

>>> x = lambda: (not(True)) in [False, True]
>>> dis.dis(x)
  1           0 LOAD_GLOBAL              0 (True)
              3 UNARY_NOT           
              4 LOAD_GLOBAL              1 (False)
              7 LOAD_GLOBAL              0 (True)
             10 BUILD_LIST               2
             13 COMPARE_OP               6 (in)
             16 RETURN_VALUE        

72
2017-07-15 04:39



Priorité de l'opérateur. in se lie plus étroitement que not, donc votre expression est équivalente à not((True) in [False, True]).


35
2017-07-15 04:17



C'est a propos de priorité de l'opérateur (in est plus fort que not). Mais il peut être facilement corrigé en ajoutant des parenthèses au bon endroit:

(not(True)) in [False, True]  # prints true

l'écriture:

not(True) in [False, True]

est le même comme:

not((True) in [False, True])

qui a l'air si True est dans la liste et renvoie le "non" du résultat.


33
2017-07-15 04:17



Il évalue comme not True in [False, True], qui revient False car True est dans [False, True] 

Si tu essayes

>>>(not(True)) in [False, True]
True

Vous obtenez le résultat attendu.


14
2017-07-15 04:18



A côté des autres réponses qui ont mentionné la préséance de not est inférieur à inEn fait, votre déclaration équivaut à:

not (True in [False, True])

Mais notez que si vous ne séparez pas votre condition des autres, python utilisera 2 rôles (precedence ou chaining) afin de séparer cela, et dans ce cas python utilisé la précédence. Notez également que si vous souhaitez séparer une condition, vous devez placer toute la condition entre parenthèses, pas seulement l'objet ou la valeur:

(not True) in [False, True]

Mais comme mentionné, il y a une autre modification par python sur les opérateurs qui est chaînage:

Basé sur python Documentation :

Notez que les comparaisons, les tests d'appartenance et les tests d'identité ont tous la même préséance et ont une gauche à droite chaînage fonction décrite dans la section Comparaisons.

Par exemple, le résultat de l'instruction suivante est False:

>>> True == False in [False, True]
False

Parce que python enchaînera les instructions comme suit:

(True == False) and (False in [False, True])

Qui est exactement False and True C'est False.

Vous pouvez supposer que l'objet central sera partagé entre 2 opérations et d'autres objets (False dans ce cas).

Et notez que cela est également vrai pour toutes les comparaisons, y compris les tests d’adhésion et les opérations de tests d’identité qui font suite aux opérandes:

in, not in, is, is not, <, <=, >, >=, !=, ==

Exemple :

>>> 1 in [1,2] == True
False

Un autre exemple célèbre est la gamme de numéros:

7<x<20

qui est égal à:

7<x and x<20   

13
2017-07-16 15:07



Voyons cela comme une opération de vérification de confinement de collection: [False, True] est une liste contenant des éléments.

L'expression True in [False, True]résultats True, comme True est un élément contenu dans la liste.

Donc, not True in [False, True] donne le "contraire booléen", not résultat de l'expression ci-dessus (sans parenthèses pour préserver la priorité, comme in a plus de priorité que not opérateur). Donc, not True résultera False.

D'autre part, (not True) in [False, True], est égal à False in [False, True], lequel est True (False est contenu dans la liste).


6
2017-07-15 19:05



Pour clarifier certaines des autres réponses, en ajoutant des parenthèses après un opérateur unaire ne change pas de priorité. not(True) ne fait pas not lier plus étroitement à True. C'est juste un ensemble redondant de parenthèses autour True. C'est à peu près la même chose que (True) in [True, False]. Les parenthèses ne font rien. Si vous voulez que la liaison soit plus serrée, vous devez placer les parenthèses autour de toute l'expression, c'est-à-dire l'opérateur et l'opérande, c'est-à-dire (not True) in [True, False].

Pour voir cela d'une autre manière, considérez

>>> -2**2
-4

** se lie plus étroitement que -, ce qui explique pourquoi vous obtenez le négatif de deux carrés, pas le carré des deux négatifs (qui serait positif quatre).

Et si vous vouliez le carré de deux négatifs? De toute évidence, vous ajoutez des parenthèses:

>>> (-2)**2
4

Cependant, il n'est pas raisonnable de s'attendre à ce que 4

>>> -(2)**2
-4

car -(2) est le même que -2. Les parenthèses ne font absolument rien. not(True) est exactement la même chose.


6
2017-07-19 00:12