Boolean tricks

¿Por qué funciona…?

lambda x: (x % 2 and 'odd' or 'even')

Porque, en primer lugar, los string no vacíos tienen valor de verdad True, el número 0 de False, y el 1 de True.

En segundo lugar hay que recordar:

True and True -> True
True and False -> False
False and False -> False

True or True -> True
True or False -> True
False or False -> False

En tercer lugar, hay que entender que las operaciones booleanas en Python realmente no evalúan la carga de verdad del enunciado completo, no es necesario.

Las operaciones and and or en Python se detienen cuando la respuesta queda determinada, y entonces devuelven el valor del último objeto escaneado. De esta forma, si tenemos:

True or False

El programa realmente no leerá a partir del or, dado que con que una de las dos proposiciones sea verdadera (y la primera lo es), el resultado será verdadero.

En cambio:

True and False

En este caso se verá obligado a leerlo entero dado que necesita conocer las dos proposiciones para deducir la carga de verdad del enunciado.

En ambos casos Python devuelve el último booleano que leyó antes de detenerse. En el primero devuelve True, en el segundo devuelve False.

Todo esto posibilita que emerjan comportamientos más sofisticados, como el que hemos visto al principio.

def funt(x):
    return(x%2 and 'odd' or 'even')


print((x%2 and 'odd' or 'even'))
print((x%2 and 'odd' or 'even'))

print((0 and 'odd' or 'even'))
print((1 and 'odd' or 'even'))

print((False and 'odd' or 'even')) -> even
print((True and 'odd' or 'even')) -> odd

Las dos primeras líneas son la función lambda del inicio reescrita como una función al uso.

Las dos siguientes son los retornos de la función para el caso de un x par e impar, respectivamente.

En las dos posteriores se ha sustituido el operador x%2 (el resto de dividir el número entre 2) por 0 si el número es par, o 1 si no lo es.

En las siguientes dichos números se han sustituido por su booleano correspondiente.

Ahora, como hemos visto, en el primer caso el programa lee «False and…», y no necesita seguir leyendo, se queda con False. Luego ese resultado entra en la siguiente operación booleana como «False or ‘even’ «, y aquí sí debe leerlo entero y se queda con «even».

En el primer caso el programa lee «True and ‘odd’» y se queda con odd, y este entra como «‘odd’ or…» y el programa se queda con «odd».

De esta forma podemos calcular si el número es par o impar sin usar un solo condicional.