Prioridad de las declaraciones lógicas NOT AND & OR en Python

81

Hasta donde yo sé, en C & C ++, la secuencia de prioridad para NOT AND & OR es NOT> AND> OR. Pero esto no parece funcionar de manera similar en Python. Intenté buscarlo en la documentación de Python y fallé (supongo que estoy un poco impaciente). ¿Alguien puede aclarar esto por mí?

Akshar Gupta
fuente
2
¿Puede dar un ejemplo en el que la precedencia del operador no funcione como cree?
dodgethesteamroller
no es mayor que y es mayor que o
CtrlAltF2

Respuestas:

93

NO, Y, O, de mayor a menor según la documentación sobre la precedencia del operador

Aquí está la tabla de precedencia completa, de menor a mayor precedencia. Una fila tiene la misma precedencia y encadena de izquierda a derecha

 0. :=
 1. lambda
 2. ifelse
 3. or
 4. and
 5. not x
 6. in, not in, is, is not, <, <=, >, >=, !=, ==
 7. |
 8. ^
 9. &
 10. <<, >>
 11. +, -
 12. *, @, /, //, %
 13. +x, -x, ~x
 14. **
 14. await x
 15. x[index], x[index:index], x(arguments...), x.attribute
 16. (expressions...), [expressions...], {key: value...}, {expressions...}
Kyle Heuton
fuente
1
Tenga en cuenta que **tiene algunas excepciones señaladas en una nota al pie cuando se trata de la precedencia sobre los operadores aritméticos.
Martijn Pieters
1
Esto confunde al matemático que hay en mí: en aritmética, diríamos que tiene precedencia sobre los operadores aritméticos. A su derecha, el **operador no tiene precedencia sobre las operaciones aritméticas, pero tiene a su izquierda ... Por ejemplo 5*2**2 == 5*(2**2),. Sin embargo, es correcto decir eso 2**-1 == 2**(-1).
PhilMacKay
@PhilMacKay: puede parecer que, por ejemplo, el signo menos es parte del intliteral, pero cuando se analiza con astno es el caso, es UnaryOpcon USuby 1como operando. La verdadera razón es que no hay otra forma de analizarlo. Es decir, 2**no es un operando izquierdo correcto para binario menos. Por lo tanto, "excepción de prioridad de exponenciación", pero "solo a la derecha".
Tomasz Gandor
32

Puede realizar la siguiente prueba para averiguar la precedencia de andy or.

Primero, intente 0 and 0 or 1en la consola de Python

Si se orune primero, lo esperaríamos 0como salida.

En mi consola, 1está la salida. Significa andque se une primero o igual a or(tal vez las expresiones se evalúen de izquierda a derecha).

Entonces inténtalo 1 or 0 and 0.

Si ory se andenlazan igualmente con el orden de evaluación integrado de izquierda a derecha, entonces deberíamos obtener 0como salida.

En mi consola, 1está la salida. Entonces podemos concluir que andtiene mayor prioridad que or.

nos
fuente
3
Más explícitamente, las expresiones se evalúan como: ((0 and 0) or 1)y(1 or (0 and 0))
Conchylicultor
1
Sin embargo, en la segunda expresión, (0 and 0)nunca se evalúa como (exp1 or exp2)retorno directo si exp1es True. De manera similar, en la primera expresión, la and 0parte nunca se evalúa como exp1 and exp2retorno directo si exp1es False.
Conchylicultor
4

De los operadores booleanos, la precedencia, del más débil al más fuerte, es la siguiente:

  1. or
  2. and
  3. not x
  4. is not; not in

Cuando los operadores tienen la misma precedencia, la evaluación procede de izquierda a derecha.

Oswald Wirt
fuente
Lo siento, su n. ° 2 es técnicamente correcto pero aún muy engañoso En primer lugar, el documento no parece cambiar. En segundo lugar, su opinión # 2 (sugiriendo and& not xse evalúa de izquierda a derecha) es técnicamente equivalente al efecto oficial, pero eso es simplemente porque cuando está en "cond1 y no cont2", Python tiene que calcular cont2 primero por defecto.
RayLuo
Gracias @RayLuo, pero ni siquiera era técnicamente correcto. Estaba colocando significado en las líneas representadas incorrectamente que dividen las filas en esa tabla. Mirando el documento 2.7 hoy or y andparece estar en la misma celda usando Firefox pero no Opera . La diferencia en la precedencia entre ory andes obvia (por ejemplo, 1 or 0 and 0vs (1 or 0) and 0) que entre andy not xno tanto por la razón que usted da. Repararé mi respuesta para reflejar lo que realmente dice la documentación .
Oswald Wirt
2

No hay una buena razón para que Python tenga otra secuencia de prioridad de esos operadores que una bien establecida en (casi) todos los demás lenguajes de programación, incluido C / C ++.

Puede encontrarlo en The Python Language Reference , parte 6.16 - Precedencia del operador, descargable (para la versión actual y empaquetado con toda la demás documentación estándar) de https://docs.python.org/3/download.html , o leerlo en línea aquí: 6.16. Precedencia del operador .

Pero todavía hay algo en Python que puede engañarlo: el resultado de los operadores andy orpuede ser diferente de Trueo False- vea 6.11 Operaciones booleanas en el mismo documento.

MarianD
fuente
1

Algunos ejemplos sencillos; observe la precedencia del operador (no, y, o); entre paréntesis para ayudar a la interpretación humana.

a = 'apple'
b = 'banana'
c = 'carrots'

if c == 'carrots' and a == 'apple' and b == 'BELGIUM':
    print('True')
else:
    print('False')
# False

Similar:

if b == 'banana'
True

if c == 'CANADA' and a == 'apple'
False

if c == 'CANADA' or a == 'apple'
True

if c == 'carrots' and a == 'apple' or b == 'BELGIUM'
True

# Note this one, which might surprise you:
if c == 'CANADA' and a == 'apple' or b == 'banana'
True

# ... it is the same as:
if (c == 'CANADA' and a == 'apple') or b == 'banana':
True

if c == 'CANADA' and (a == 'apple' or b == 'banana'):
False

if c == 'CANADA' and a == 'apple' or b == 'BELGIUM'
False

if c == 'CANADA' or a == 'apple' and b == 'banana'
True

if c == 'CANADA' or (a == 'apple' and b == 'banana')
True

if (c == 'carrots' and a == 'apple') or b == 'BELGIUM'
True

if c == 'carrots' and (a == 'apple' or b == 'BELGIUM')
True

if a == 'apple' and b == 'banana' or c == 'CANADA'
True

if (a == 'apple' and b == 'banana') or c == 'CANADA'
True

if a == 'apple' and (b == 'banana' or c == 'CANADA')
True

if a == 'apple' and (b == 'banana' and c == 'CANADA')
False

if a == 'apple' or (b == 'banana' and c == 'CANADA')
True
Victoria Stuart
fuente