python opérateur “ou” comportement bizarre
D'abord, le code:
>>> False or 'hello'
'hello'
Ce comportement étonnant vous permet de vérifier si x != Aucun et vérifier la valeur de x en une seule ligne:
>>> x = 10 if randint(0,2)==1 else None
>>> (x or 0) > 0
depend on x value...
Explication: "ou" fonctionne comme ceci: (lien)
"si x est faux, alors y, d'autre x"
Aucune langue que je sais vous permet de faire cela.
Alors, pourquoi Python?
Voulez-vous dire
Javascript:
La vraie question est pourquoi ne pas ce sera une fonctionnalité de Python? Pourquoi l'hypothèse être vous ne pouvez pas faire quelque chose? Est ce que cela a des effets négatifs?
je veux dire: (Aucun ou 0) < 1 (ce qui est Vrai).
x or x > 0
? Et c'est de court-circuit de l'évaluation -- beaucoup de langues vous permettent de le faire.Javascript:
val || default
?La vraie question est pourquoi ne pas ce sera une fonctionnalité de Python? Pourquoi l'hypothèse être vous ne pouvez pas faire quelque chose? Est ce que cela a des effets négatifs?
x or 0 > 0
ne pas vous laisser dépendent de la x
valeur. En fait, il n'a aucun effet. Peut-être que vous avez voulu dire x = x or 0
? Mais tout de même, c'est une chose étrange—et il pourrait tout aussi facilement être manipulé dans la ligne ci-dessus en faisant x = 10 if randint(0, 2)==1 else 0
au lieu de else None
. Alors... en fait, je n'ai aucune idée de ce que vous souhaitiez.je veux dire: (Aucun ou 0) < 1 (ce qui est Vrai).
OriginalL'auteur mclafee | 2012-12-13
Vous devez vous connecter pour publier un commentaire.
Il semble que vous êtes à la combinaison de deux questions en une seule.
Tout d'abord, il y a le problème de court-circuit. Marcin la réponse de traite de cette question parfaitement, donc je ne vais pas essayer de faire mieux.
Deuxième, il y a
or
etand
de retourner la dernière valeur évaluée, plutôt que de le convertir bool. Il y a des arguments pour être fait de deux façons, et vous pouvez trouver de nombreuses langues sur chaque côté de la fracture.De retourner la dernière valeur évaluée permet à l'
functionCall(x) or defaultValue
raccourci, évite, éventuellement, un gaspillage de la conversion (pourquoi convertir uneint
2
dans unbool
1
si la seule chose que vous allez faire, c'est de vérifier si c'est non nulle?), et il est facile à expliquer. Donc, pour diverses combinaisons de ces raisons, les langages tels que C, Lisp, Javascript, Lua, Perl, Ruby, et VB toutes les choses de cette manière, et ainsi de Python.Toujours renvoyant une valeur booléenne à partir d'un opérateur permet d'attraper quelques erreurs (en particulier dans les langues où les opérateurs logiques et les opérateurs au niveau du bit sont faciles à confondre), et il permet à la conception d'un langage où les booléens, les contrôles sont strictement tapé vérifie
true
au lieu de simplement vérifie différente de zéro, il fait le type de l'opérateur plus facile à écrire, et ça évite d'avoir à traiter avec de la conversion pour les cas où les deux opérandes sont de types différents (voir la?:
opérateur en C-de la famille des langues). Donc, pour diverses combinaisons de ces raisons, les langages tels que C++, Fortran, Smalltalk, et Haskell toutes les choses de cette manière.Dans votre question (si je comprends bien), vous utilisez cette fonctionnalité pour pouvoir écrire quelque chose comme:
Quand
x
pourrait facilement êtreNone
. Ce cas d'utilisation particulier n'est pas très utile, à la fois parce que les plus explicites de lax if x else 0
(en Python 2.5 et ultérieur) est tout aussi facile à écrire et probablement plus facile à comprendre (au moins Guido pense que oui), mais aussi parce queNone < 1
est le même que0 < 1
de toute façon (au moins en Python 2.x, de sorte que vous avez toujours au moins l'une des deux options)... Mais il existe aussi des exemples où il est utile. Comparer ces deux:La seconde va perdre beaucoup de missiles exploser vos ennemis dans l'Antarctique, deux fois au lieu d'une fois.
Si vous êtes curieux de savoir pourquoi Python est-il de cette façon:
De retour dans le 1.les x jours, il y était pas
bool
type. Vous avez falsy des valeurs commeNone
,0
,[]
,()
,""
, etc., et tout le reste est vrai, alors, qui doit expliciteFalse
etTrue
? De retour1
deor
aurait été idiot, parce que1
n'est pas plus vrai que[1, 2, 3]
ou"dsfsdf"
. Par les tempsbool
a été ajouté (progressivement plus de deux 2.versions x, IIRC), la logique était déjà solidement ancrées dans la langue, et l'évolution aurait brisé beaucoup de code.Alors, pourquoi n'ont-ils pas le changer en 3.0? De nombreux Python utilisateurs, y compris BDFL Guido, suggère que vous ne devriez pas utiliser
or
dans ce cas (à tout le moins parce que c'est une violation de "TOOWTDI"); en revanche, vous pouvez stocker le résultat de l'expression dans une variable, par exemple:Et en fait, Guido a déclaré qu'il aimerait ban
launchMissiles() or -1
, et c'est en partie la raison pour laquelle il a finalement accepté le ternaireif
-else
expression qu'il avait rejeté de nombreuses fois avant. Mais beaucoup d'autres sont en désaccord, et Guido est un bienveillant DFL. Aussi, faireor
fonctionne de la façon que vous attendez partout ailleurs, tout en refusant de faire ce que vous voulez (mais Guido ne veut pas que vous voulez), ici, serait en fait assez compliqué.Donc, Python sera probablement toujours être sur le même côté que le C, Perl, Lisp et ici, au lieu de le même côté que Java, Smalltalk, et Haskell.
or
etand
ne retourne pas de valeurs booléennes a été l'une des choses qui m'a vraiment surpris dans un premier temps avec python. Après un certain temps cependant, vous vous habituez à elle (et à apprendre à l'utiliser pour jouer quelques trucs 🙂Ne pas
gfortran
ont 3000 drapeaux de contrôle qui Fortran 77 dialecte qu'il utilise? De toute façon, je suis au moins sur Fortran retournant un booléen? BTW, j'ai été aussi surpris que Pythonor
etand
ne pas retourner bool (ou1
et0
, parce qu'il n'y a pas debool
encore), mais pas tout à fait pour la même raison. J'ai attendu que, compte tenu de la chance d'être comme Smalltalk et C++, ou comme Perl et C, Python aurait choisi l'ancien... Mais une fois que j'ai réalisé que1
n'était pas quelque chose de spécial (et vraiment,True
n'est toujours pas), il fait sens.FWIW, Python 3.x ne permet pas de
None < 1
(poseTypeError
).Bon point, permettez-moi de modifier la réponse. Merci.
OriginalL'auteur abarnert
Vous ne savez pas de nombreuses langues. Je ne peux pas penser à une langue que je ne sais qui ne présentent pas ce "court-circuit" de comportement.
Il le fait parce qu'il est utile de dire:
tels que a devient b, si b n'est pas Nulle (ou autrement falsy), et si non il est la valeur par défaut K.
Fortran, Pascal, et Algol68 ne pas faire de court-circuit. (Eh bien, beaucoup de Pascals faire, mais d'origine et de l'ISO ne fait pas, et Algol vous donne un moyen de définir votre propre court-circuit opérateurs.) Aussi, de nombreux paresseux langues, techniquement, ne pas faire de court-circuit parce qu'ils n'ont pas besoin. Mais de toute façon, je doute que l'OP est venue à Python de Fortran ou LazyML...
"Je ne peux pas penser à une langue que je ne sais qui n'a pas de" c++, c#, java, PHP, etc. ils retournent tous valeur booléenne! réfléchir à nouveau.
Je crois qu'il parle de défaut de convertir bool, pas de court-circuit.
Bien sûr!
x = [] or [1, 2, 3]
jeux dex
à[1, 2, 3]
en Python. L'équivalent en C++ ou en Haskell jeux dex
àTrue
. C'est un énorme différence.OriginalL'auteur Marcin
En fait un certain nombre de langues. Voir Wikipédia à propos de Évaluation De Court-Circuit
Pour la raison pourquoi évaluation de court-circuit existe, wikipedia a écrit:
Je pense que la question est plus sur le retour de la première non-faux-comme l'objet, au lieu d'un booléen. C fait cela, C++ et Java ne le font pas.
OriginalL'auteur hexparrot
Ce comportement n'est pas surprenant, et il est assez simple si vous envisagez de Python a les caractéristiques suivantes concernant ou, et et pas opérateurs logiques:
bool
.Et, en outre:
None
,False
,0
,""
,[]
,{}
. Tout le reste a une valeur de vérité Vrai (c'est une simplification; la définition correcte est dans le officiel docs)De combiner ces caractéristiques, et il conduit à:
C'est plus facile à comprendre si vous généralisez à une chaîne d'opérations:
Ici est la "règle du pouce" j'ai mémorisé pour m'aider à facilement prédire le résultat:
Quant à votre question, sur pourquoi python se comporte comme ça, eh bien... je pense qu'il y a un très soigné utilise, et c'est assez intuitif à comprendre. Une utilisation courante est une série de secours de choix, la première "trouvé" (c'est à dire, non-falsy) est utilisé. Pensez à ce stupide exemple:
Ou ce monde réel scénario:
Qui est beaucoup plus concis et élégant que l'alternative.
Comme beaucoup d'autres réponses ont souligné, Python n'est pas le seul et de nombreuses autres langues ont le même comportement, à la fois de court-circuit (je crois plus actuel languanges) et non de la coercition.
suite à votre suggestion, j'ai changé les majuscules, les événements et les quelques autres cas / orthographe des améliorations
OriginalL'auteur MestreLion
"Aucune langue que je sais vous permet de faire cela. Alors, pourquoi Python?" Vous semblez supposer que toutes les langues doivent être les mêmes. Ne serait-il pas s'attendre à de l'innovation dans les langages de programmation pour produire des caractéristiques uniques que les gens de valeur?
Vous avez tout a fait pourquoi il est utile, alors pourquoi ne pas en Python? Peut-être que vous devriez demander pourquoi d'autres langues n'en ont pas.
OriginalL'auteur Ned Batchelder