2010-07-05 9 views
15
o

en Python si escriben algo así comoPython expresión booleana y

foo==bar and spam or eggs 

pitón parece volver correo no deseado si la expresión booleana es verdadera y huevos de otra manera. ¿Podría alguien explicar este comportamiento? ¿Por qué la expresión no se evalúa como un booleano largo?

Editar: Específicamente, estoy tratando de descubrir el mecanismo por el cual 'spam' o 'eggs' se devuelve como resultado de la expresión.

Respuesta

14

Los operadores and y or son cortocircuitos que significa que si el resultado de la expresión se puede deducir de evaluar sólo la primera operando, el segundo no se evalúa. Por ejemplo, si tiene la expresión a or b y a se evalúa como verdadera, entonces no importa qué sea b, el resultado de la expresión es verdadero, por lo que b no se evalúa. En realidad funcionan de la siguiente manera:

  • a and b: Si a es Falsey-, b no se evalúa y se devuelve una, de lo contrario se devuelve b.
  • a or b: Si a es cierto, b no se evalúa y a se devuelve, de lo contrario se devuelve b.

Falsey y truthy hacen referencia a valores que se evalúan como falso o verdadero en un contexto booleano.

Sin embargo esto y/o idioma era útil en los días cuando no había ninguna alternativa mejor, pero ahora hay una manera mejor:

spam if foo==bar else eggs 

El problema con el y/o idioma (aparte de ella siendo confuso para los principiantes) es que da el resultado incorrecto si la condición es verdadera, pero el correo no deseado evalúa a un valor falsey (por ejemplo, la cadena vacía). Por esta razón, debes evitarlo.

+1

'spam if foo == bar or eggs' muestra un error de sintaxis en python 2.6.5, pero 'spam if foo == bar else eggs' funciona como se esperaba. – Zxaos

+0

@Zxaos: Perdón por eso. Debería haber sido 'else' no' o'. Corregido ahora. –

+1

En "el resultado incorrecto ... si foo evalúa a un valor de falsey", ¿quiso decir "spam evalúa a un valor Falsey"? – unutbu

2

Intenta usar paréntesis para hacer que la expresión no sea ambigua. La forma en que está, que está recibiendo:

(foo == bar and spam) or eggs 
+0

+1 para mí vencer a ella – derekerdmann

+0

entiendo que es ser cortocircuitado, pero estoy seguro de por qué están siendo devueltos spam o los huevos como resultado de la evaluación. – Zxaos

3

La razón es que Python evalúa la expresión booleana usando los valores reales de las variables que intervienen, en lugar de restringirlos a True y False valores. Los siguientes valores se consideran ser falsa:

  • None
  • False
  • 0 de cualquier tipo numérico
  • secuencia vacía o conjunto ('', (), [], {}) definido por el usuario
  • tipos con __nonzero__() o __len__() método que devuelve 0 o False

Consulte la sección Truth Value Testing de la documentación de Python para obtener más información. En particular:

Operaciones y funciones incorporadas que tienen un resultado booleano siempre vuelven 0 o False por falsa y 1 o True por cierto, a menos que se indique lo contrario. (Excepción importante:. Las operaciones booleanas or y and siempre devolver uno de sus operandos)

+0

Ok, así que supongamos que foo y bar son iguales. El intérprete debe entonces evaluar True y spam, que debe evaluar True, entonces, ¿por qué se devuelve el spam? Editar: Ah, vale. Veo de los documentos. – Zxaos

+0

@ Zxaos: actualicé mi respuesta con la cita de la documentación que explica el motivo. –

5

Así es como funcionan los operadores booleanos de Python.

De the documentation (el último párrafo explica por qué es una buena idea que los operadores funcionan de la manera que lo hacen):

En el contexto de las operaciones booleanas, y también cuando las expresiones son utilizadas por de control estados de flujo, las siguientes valores se interpretan como falsa: False, None, numérico cero de todos los tipos , y cadenas vacías y contenedores (incluyendo cadenas, tuplas, listas, diccionarios, conjuntos y conjuntos congelados). Todos los demás valores son interpretados como verdaderos. (Véase el método especial __nonzero__() una manera de cambiar esto.)

El operador not produce True si su argumento es falso , False lo contrario.

La expresión x and y primero evalúa x; si x es falso, su valor es devuelto; de lo contrario, y se evalúa y se devuelve el valor resultante.

La expresión x or y primero evalúa x; si x es verdadero, su valor es devuelto; de lo contrario, y se evalúa y se devuelve el valor resultante.

(Tenga en cuenta que ni and ni or restringir el valor y tipo regresan a False y True, sino más bien devolver el argumento evaluado por última vez. Esto es veces es útil, por ejemplo, si s es una cadena que debe ser reemplazado por un valor predeterminado si está vacío, la expresión s or 'foo' se obtiene el valor deseada. Debido not tiene que inventar un valor de todas formas, no se molestan en devolver un valor de la misma tipo como su argumento, por lo que por ejemplo, not 'foo' produce False, no ''.)

+0

+1 para el enlace a documentos. –

Cuestiones relacionadas