positivos - python positivo negativo
Dado 2 valores int, devuelve True si uno es negativo y el otro es positivo (4)
def logical_xor(a, b): # for example, -1 and 1
print (a < 0) # evaluates to True
print (b < 0) # evaluates to False
print (a < 0 != b < 0) # EVALUATES TO FALSE! why??? it''s True != False
return (a < 0 != b < 0) # returns False when it should return True
print ( logical_xor(-1, 1) ) # returns FALSE!
# now for clarification
print ( True != False) # PRINTS TRUE!
¿Alguien podría explicar lo que está sucediendo? Estoy tratando de hacer un trazador de líneas:
lambda a, b: (a < 0 != b < 0)
En Python, los operadores de comparación tienen la misma precedencia y no son asociativos. Existe una regla separada para secuencias de operadores de comparación, la regla de encadenamiento. La documentación de Python dice acerca de eso:
si
a, b, c, ..., y, z
son expresiones yop1, op2, ..., opN
son operadores de comparación, entonces aop1 b op2 c ... y opN z
es equivalente aa op1 b and b op2 c and ... y opN z
, excepto que cada expresión se evalúa como máximo una vez.
Además, a op1 b and b op2 c and ... y opN z
evalúa de izquierda a derecha.
a < 0 and 0 != b and b < 0
a < 0
se evaluará a False
, y la evaluación adicional se detendrá debido a la evaluación de cortocircuito . Entonces, toda la expresión será evaluada como False
.
Puedes usar esto
return (a < 0) != (b < 0)
Las comparaciones se pueden encadenar arbitrariamente, por ejemplo, x <y <= z es equivalente a x <yy <= z, excepto que y se evalúa solo una vez (pero en ambos casos z no se evalúa cuando x <y se encuentra ser falso).
Entonces se vuelve
(a < 0) and (0 != b) and (b < 0)
Ver https://docs.python.org/3/reference/expressions.html#not-in
Todos los operadores de comparación en Python tienen la misma precedencia. Además, Python realiza comparaciones encadenadas. Así,
(a < 0 != b < 0)
se descompone como:
(a < 0) and (0 != b) and (b < 0)
Si alguno de estos es falso, el resultado total de la expresión será False
.
Lo que quiere hacer es evaluar cada condición por separado, así:
(a < 0) != (b < 0)
Otras variantes, de los comentarios:
(a < 0) is not (b < 0) # True and False are singletons so identity-comparison works
(a < 0) ^ (b < 0) # bitwise-xor does too, as long as both sides are boolean
(a ^ b < 0) # or you could directly bitwise-xor the integers;
# the sign bit will only be set if your condition holds
# this one fails when you mix ints and floats though
(a * b < 0) # perhaps most straightforward, just multiply them and check the sign
Su código no funciona como se esperaba porque !=
Tiene mayor prioridad que a < 0
y b < 0
.Como itzmeontv sugiere en su respuesta, usted puede simplemente decidir la precedencia usted mismo rodeando los componentes lógicos con paréntesis:
(a < 0) != (b < 0)
Tu código intenta evaluar a < (0 != b) < 0
[EDITAR]
Como acertadamente señala tzaman, los operadores tienen la misma precedencia, pero el código intenta evaluar (a < 0) and (0 != b) and (b < 0)
. Rodear tus componentes lógicos con paréntesis resolverá esto:
(a < 0) != (b < 0)
Precedente del operador: https://docs.python.org/3/reference/expressions.html#operator-precedence
Comparaciones (es decir, encadenamiento): https://docs.python.org/3/reference/expressions.html#not-in