validar positivos positivo numeros numero negativos negativo python python-3.x return logical-operators

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 y op1, op2, ..., opN son operadores de comparación, entonces a op1 b op2 c ... y opN z es equivalente a a 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