32 votes

L'opérateur in (__contains__) de Python renvoie un bool dont la valeur n'est ni vraie ni fausse.

Comme prévu, 1 n'est pas contenu par le tuple vide

>>> 1 in ()
False

mais le False la valeur renvoyée n'est pas égale à False

>>> 1 in () == False
False

D'un autre point de vue, le in L'opérateur retourne un bool qui n'est ni True ni False :

>>> type(1 in ())
<type 'bool'>
>>> 1 in () == True, 1 in () == False
(False, False)

Cependant, le comportement normal reprend si l'expression originale est mise entre parenthèses

>>> (1 in ()) == False
True

ou sa valeur est stockée dans une variable

>>> value = 1 in ()
>>> value == False
True

Ce comportement est observé à la fois dans Python 2 et Python 3.

Pouvez-vous expliquer ce qui se passe ?

45voto

Martijn Pieters Points 271458

Vous vous heurtez au chaînage des opérateurs de comparaison ; 1 in () == False fait pas moyenne (1 in ()) == False .

Au contraire, les comparaisons sont enchaînées et l'expression signifie réellement :

(1 in ()) and (() == False)

Parce que (1 in ()) est déjà fausse, la seconde moitié de l'expression chaînée est ignorée (car False and something_else renvoie à False quelle que soit la valeur de something_else serait).

Voir le documentation sur les comparaisons et les expressions :

Les comparaisons peuvent être enchaînées arbitrairement, par exemple, x < y <= z est équivalent à x < y and y <= z sauf que y n'est évalué qu'une seule fois (mais dans les deux cas z n'est pas évalué du tout lorsque x < y s'avère être fausse).

Pour mémoire, < , > , == , >= , <= , != , is , is not , in y not in sont tous des opérateurs de comparaison (tout comme le déprécié <> ).

En général, ne comparez pas les booléens ; testez simplement l'expression elle-même. Si vous ont pour effectuer un test par rapport à un littéral booléen, utilisez au moins les parenthèses et la balise is opérateur, True y False sont des singletons, tout comme None :

>>> (1 in ()) is False
True

Cela devient encore plus confus lorsque des nombres entiers sont impliqués. La méthode Python bool est une sous-classe de int 1 . En tant que tel, False == 0 est vrai, tout comme True == 1 . Il est donc possible de créer des opérations enchaînées qui ont l'air presque normales :

3 > 1 == True

est vrai parce que 3 > 1 y 1 == True sont toutes deux vraies. Mais l'expression :

3 > 2 == True

est fausse, car 2 == True est fausse.

1 <code>bool</code> est une sous-classe de <code>int</code> pour des raisons historiques ; Python n'a pas toujours eu un <code>bool</code> et des entiers surchargés avec une signification booléenne, comme le fait le C. Création de <code>bool</code> une sous-classe a permis à l'ancien code de fonctionner.

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