Tres palabras en lugar de símbolos
Los operadores lógicos de Python son las palabras inglesas and, or y not. Otros lenguajes los escriben &&, || y !. En Python && y || son un SyntaxError, y ! solo aparece como parte de != ("distinto de").
Con True y False las reglas son las que esperas:
a | b | a and b | a or b | not a |
|---|---|---|---|---|
True | True | True | True | False |
True | False | False | True | False |
False | True | False | True | True |
False | False | False | False | True |
and necesita que ambos lados sean verdaderos. or necesita al menos uno. not toma un solo valor y lo invierte.
En código real los lados suelen ser comparaciones, y el resultado alimenta un if o un while:
Salida:
eligible
standard ticket
Con eso basta para la mayoría de las condiciones. El resto de esta página cubre qué hacen los operadores con valores que no son True ni False, y las reglas que deciden qué lado de una expresión se ejecuta.
Valores truthy y falsy
and, or y not aceptan cualquier valor, no solo booleanos. Python decide si un valor cuenta como verdadero según su valor de verdad. Estos valores son falsy:
FalseyNone- el cero de cualquier tipo numérico:
0,0.0 - los contenedores y strings vacíos:
"",[],(),{},set(),range(0)
Todo lo demás es truthy, incluidos "0", "False", [0] y -1. Puedes ver cómo clasifica Python un valor con bool():
Salida:
0 False
1 True
-1 True
'' False
'0' True
[] False
[0] True
None False
0.0 False
El string "0" es truthy porque es un string no vacío. Este caso pilla a quien lee números de la entrada y los comprueba antes de convertirlos. La página de números y booleanos explica cómo se relaciona bool con int.
and y or devuelven un operando
Aquí es donde Python se diferencia de la mayoría de los lenguajes. and y or no producen un True o False nuevo. Devuelven uno de los dos valores que les diste:
x or ydevuelvexsixes truthy; si no, devuelvey.x and ydevuelvexsixes falsy; si no, devuelvey.
Cuando ambos operandos son booleanos, "devolver un operando" y "devolver un booleano" son lo mismo, y por eso la diferencia pasa desapercibida hasta que mezclas otros tipos.
not es la excepción: siempre devuelve True o False.
Si necesitas un booleano real de una expresión con and/or, por ejemplo para guardarlo o devolverlo desde una función que promete un bool, envuélvela en bool():
Evaluación en cortocircuito
Python evalúa and y or de izquierda a derecha y se detiene en cuanto conoce la respuesta:
andse detiene en el primer valor falsy, porque nada de lo que venga después puede hacer verdadera la expresión completa.orse detiene en el primer valor truthy, porque nada de lo que venga después puede hacer falsa la expresión completa.
El lado que se salta no se ejecuta en absoluto. Puedes verlo con funciones que imprimen algo cuando se las llama:
Salida:
and:
checking A
False
or:
checking A
True
B no se comprueba en ninguno de los dos casos. El cortocircuito es lo que hace seguras las condiciones de guarda. La segunda mitad de cada condición de abajo fallaría por sí sola, pero solo se ejecuta cuando la primera mitad ya ha descartado el caso problemático:
Pon primero la prueba barata o la que protege. Si inviertes el orden, user.startswith("admin") and user is not None lanza AttributeError cuando user es None.
Patrones construidos sobre or y and
Como or devuelve su primer operando truthy, sirve para dar un valor por defecto en una línea:
Salida:
Hello, Ada!
Hello, guest!
Hello, guest!
El problema es que or reemplaza cualquier valor falsy, no solo None. Si 0, "" o [] son entradas legítimas, or las descartará:
Usa x if x is not None else default cuando cero o vacío sea un valor válido. La página de if/else explica esa expresión condicional.
and tiene un patrón equivalente: "usa este valor solo si el primero está definido". Es menos común y a menudo queda más claro como un if, así que úsalo con moderación:
Precedencia: not, luego and, luego or
Cuando una expresión mezcla los tres, Python aplica primero not, luego and y luego or. Las comparaciones como ==, < e in se aplican antes que cualquiera de ellos.
a or b and c y (a or b) and c dan respuestas distintas con los mismos valores, así que una condición mixta debería llevar paréntesis aunque el orden por defecto resulte ser el correcto. No cuestan nada y le ahorran la duda al siguiente lector.
and/or frente a &/|
& y | se parecen a and y or y a veces dan la misma respuesta, pero son operadores distintos.
and/orcomprueban el valor de verdad, hacen cortocircuito y devuelven uno de los operandos.&/|son operadores bitwise. Con enteros combinan los bits de los dos números. Con sets significan intersección y unión. ConTrueyFalsedevuelven un booleano. Nunca hacen cortocircuito: siempre se evalúan ambos lados.
Los operadores bitwise además tienen mayor precedencia que las comparaciones, lo que convierte una condición escrita con & en algo completamente distinto:
1 & y es 1 & 5, que vale 1, así que la línea del medio se convierte en la cadena 5 > 1 > 1, y 1 > 1 es falso. En código Python normal, usa and, or y not para las condiciones.
El único sitio donde &, | y ~ son correctos en condiciones es NumPy y pandas. Un array contiene muchos valores, así que no tiene un único valor de verdad, y and lanza ValueError: The truth value of an array ... is ambiguous. Estas bibliotecas sobrecargan & y | para que trabajen elemento a elemento, y por eso los filtros de pandas tienen la forma df[(df.age > 18) & (df.country == "CA")], con paréntesis alrededor de cada comparación por el motivo de precedencia de arriba.
any() y all(): and y or sobre una lista
Para combinar una secuencia entera de condiciones, usa las funciones integradas all() (un and sobre todos los elementos) y any() (un or sobre todos los elementos). Ambas hacen cortocircuito de la misma manera:
A diferencia de and y or, any() y all() siempre devuelven un booleano.
Errores comunes
Comparar una variable con varios valores usando or. Esta condición siempre es verdadera:
Python lee la primera condición como (color == "red") or "blue". La comparación es False, así que or devuelve "blue", un string no vacío, que es truthy. Repite la comparación en ambos lados o, mejor aún, comprueba la pertenencia con in.
Escribir && o ||. Ambos son un SyntaxError. Usa and y or.
Esperar un booleano de and/or. x = a or b guarda el propio a o b. A menudo es lo que quieres, pero si una función debe devolver True o False, convierte con bool().
Confiar en la precedencia en condiciones mixtas. a or b and c es válido y está bien definido, pero añade paréntesis para que nadie tenga que recordar la regla.
Preguntas frecuentes
¿Qué hace el operador and en Python?
a and b es verdadero solo cuando ambos lados son verdaderos. Python evalúa primero a; si a es falsy devuelve a sin mirar b, y si no, devuelve b. Con booleanos normales eso da el resultado habitual: True and False es False.
¿Por qué 0 or 5 devuelve 5 en lugar de True?
0 or 5 devuelve 5 en lugar de True?or y and devuelven uno de sus operandos, no un booleano nuevo. x or y devuelve x si x es truthy y, si no, y. 0 es falsy, así que 0 or 5 devuelve 5. Envuelve la expresión en bool() si necesitas un True o False de verdad.
¿Cuál es la diferencia entre and y & en Python?
and y & en Python?and es un operador lógico: comprueba el valor de verdad y hace cortocircuito. & es un operador bitwise: con enteros combina bits (6 & 3 es 2), con sets calcula la intersección y siempre evalúa ambos lados. Usa and en las condiciones de un if. La excepción son NumPy y pandas, donde & es el and elemento a elemento.
¿Qué se ejecuta primero en Python, and u or?
not es el que liga más fuerte, luego and y luego or. Así que a or b and c significa a or (b and c), y not a or b significa (not a) or b. Las comparaciones como == y < ligan más fuerte que los tres.
¿Puedo usar && y || en Python?
No. && y || son un SyntaxError en Python. Los operadores lógicos son las palabras and, or y not. Un solo & o | es válido pero significa otra cosa (and/or bitwise).