Подтвердить что ты не робот

Учитывая 2 значения int, верните True, если один отрицательный, а другой положительный

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 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!

Может кто-нибудь объяснить, что происходит? Я пытаюсь сделать один вкладыш:

lambda a, b: (a < 0 != b < 0)
4b9b3361

Ответ 1

Все операторы сравнения в Python имеют тот же самый приоритет. Кроме того, Python делает скованные сравнения. Таким образом,

(a < 0 != b < 0)

ломается как:

(a < 0) and (0 != b) and (b < 0)

Если какой-либо из них является ложным, итоговый результат выражения будет False.

Что вы хотите сделать, так это оценить каждое условие отдельно:

(a < 0) != (b < 0)

Другие варианты, из комментариев:

(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

Ответ 2

Ваш код не работает должным образом, потому что != принимает более высокий precedence, чем a < 0 и b < 0, Как предполагает Ицмеонтв в своем ответе, вы можете просто решить приоритет самостоятельно, окружая логические компоненты круглыми скобками:

(a < 0) != (b < 0)

Ваш код пытается оценить a < (0 != b) < 0

[EDIT]

Как правильно указывает tzaman, операторы имеют одинаковый приоритет, но ваш код пытается оценить (a < 0) and (0 != b) and (b < 0). Окружающие ваши логические компоненты круглыми скобками разрешат это:

(a < 0) != (b < 0)

Приоритет оператора: https://docs.python.org/3/reference/expressions.html#operator-precedence

Сравнение (например, цепочка): https://docs.python.org/3/reference/expressions.html#not-in

Ответ 3

Вы можете использовать этот

return (a < 0) != (b < 0)

Сравнение может быть скоблено произвольно, например, x < y <= z эквивалентно x < y и y <= z, за исключением того, что y оценивается только один раз (но в обоих случаях z вообще не оценивается, когда x < y считается ложным).

Таким образом, он становится

(a < 0) and (0 != b) and (b < 0)

См. https://docs.python.org/3/reference/expressions.html#not-in

Ответ 4

В Python операторы сравнения имеют одинаковый приоритет и неассоциативны. Существует отдельное правило для последовательностей операторов сравнения, правила цепочки. Документация Python утверждает следующее:

если a, b, c, ..., y, z - выражения, а op1, op2, ..., opN - операторы сравнения, то a op1 b op2 c ... y opN z эквивалентно a op1 b and b op2 c and ... y opN z, за исключением того, что каждое выражение оценивается не более одного раза.

Далее, a op1 b and b op2 c and ... y opN z оценивается слева направо.

 a < 0 and 0 != b and b < 0  

a < 0 будет оцениваться до False, и дальнейшая оценка будет остановлена ​​из-за оценки короткого замыкания. Таким образом, все выражение будет оцениваться как False.