Respuestas:
Sí, los dos and
y or
los operadores de corto circuito - véase la documentación .
and
, or
:Primero definamos una función útil para determinar si algo se ejecuta o no. Una función simple que acepta un argumento, imprime un mensaje y devuelve la entrada, sin cambios.
>>> def fun(i):
... print "executed"
... return i
...
Se puede observar la conducta de cortocircuito de Python de and
, or
operadores en el siguiente ejemplo:
>>> fun(1)
executed
1
>>> 1 or fun(1) # due to short-circuiting "executed" not printed
1
>>> 1 and fun(1) # fun(1) called and "executed" printed
executed
1
>>> 0 and fun(1) # due to short-circuiting "executed" not printed
0
Nota: El intérprete considera que los siguientes valores significan falso:
False None 0 "" () [] {}
any()
, all()
:Python any()
y sus all()
funciones también admiten cortocircuitos. Como se muestra en los documentos; evalúan cada elemento de una secuencia en orden, hasta encontrar un resultado que permita una salida temprana de la evaluación. Considere los ejemplos a continuación para comprender ambos.
La función any()
verifica si algún elemento es Verdadero. Deja de ejecutarse tan pronto como se encuentra un Verdadero y devuelve Verdadero.
>>> any(fun(i) for i in [1, 2, 3, 4]) # bool(1) = True
executed
True
>>> any(fun(i) for i in [0, 2, 3, 4])
executed # bool(0) = False
executed # bool(2) = True
True
>>> any(fun(i) for i in [0, 0, 3, 4])
executed
executed
executed
True
La función all()
verifica que todos los elementos sean Verdaderos y deja de ejecutarse tan pronto como se encuentre un Falso:
>>> all(fun(i) for i in [0, 0, 3, 4])
executed
False
>>> all(fun(i) for i in [1, 0, 3, 4])
executed
executed
False
Además, en Python
Las comparaciones pueden encadenarse arbitrariamente ; por ejemplo,
x < y <= z
es equivalente ax < y and y <= z
, excepto quey
se evalúa solo una vez (pero en ambos casosz
no se evalúa en absoluto cuandox < y
se determina que es falso).
>>> 5 > 6 > fun(3) # same as: 5 > 6 and 6 > fun(3)
False # 5 > 6 is False so fun() not called and "executed" NOT printed
>>> 5 < 6 > fun(3) # 5 < 6 is True
executed # fun(3) called and "executed" printed
True
>>> 4 <= 6 > fun(7) # 4 <= 6 is True
executed # fun(3) called and "executed" printed
False
>>> 5 < fun(6) < 3 # only prints "executed" once
executed
False
>>> 5 < fun(6) and fun(6) < 3 # prints "executed" twice, because the second part executes it again
executed
executed
False
Editar:
Otro punto interesante a tener en cuenta : - Lógico and
, losor
operadores en Python devuelven el valor de un operando en lugar de un booleano ( True
o False
). Por ejemplo:
La operación
x and y
da el resultadoif x is false, then x, else y
A diferencia de otros lenguajes &&
, por ejemplo , ||
operadores en C que devuelven 0 o 1.
Ejemplos:
>>> 3 and 5 # Second operand evaluated and returned
5
>>> 3 and ()
()
>>> () and 5 # Second operand NOT evaluated as first operand () is false
() # so first operand returned
Del mismo modo, el or
operador devuelve el valor más a la izquierda para el cual bool(value)
== True
más a la derecha el valor más falso (según el comportamiento de cortocircuito), ejemplos:
>>> 2 or 5 # left most operand bool(2) == True
2
>>> 0 or 5 # bool(0) == False and bool(5) == True
5
>>> 0 or ()
()
Entonces, ¿cómo es esto útil? Un ejemplo de uso dado en Practical Python por Magnus Lie Hetland:
Digamos que se supone que un usuario ingrese su nombre, pero puede optar por no ingresar nada, en cuyo caso desea usar el valor predeterminado '<unknown>'
. Podría usar una declaración if, pero también podría indicar las cosas de manera muy sucinta:
In [171]: name = raw_input('Enter Name: ') or '<Unkown>'
Enter Name:
In [172]: name
Out[172]: '<Unkown>'
En otras palabras, si el valor de retorno de raw_input es verdadero (no una cadena vacía), se le asigna un nombre (nada cambia); de lo contrario, '<unknown>'
se asigna el valor predeterminado a name
.
0
son Falsy (lo que no es justo 0
, es 0.0
, 0j
, decimal.Decimal(0)
, fractions.Fraction(0)
, etc.), como lo son todas las colecciones de longitud 0
(por lo que en la parte superior de lo que en la lista, b''
[AP3], u''
[Py2] y set()
/ frozenset()
son todos incorporados que se evalúan como falsos), pero los tipos definidos por el usuario / de terceros pueden definir los suyos propios (con __bool__
[Py3] / __nonzero__
[Py2] directamente o indirectamente definiendo __len__
).