Given 2 int values, return True if one is negative and other is positive
Your code doesn't work as intended because !=
takes higher precedence than a < 0
and b < 0
. As itzmeontv suggests in his answer, you can simply decide the precedence yourself by surrounding logical components with parentheses:
(a < 0) != (b < 0)
Your code attempts to evaluate a < (0 != b) < 0
[EDIT]
As tzaman rightly points out, the operators have the same precedence, but your code is attempting to evaluate (a < 0) and (0 != b) and (b < 0)
. Surrounding your logical components with parentheses will resolve this:
(a < 0) != (b < 0)
Operator precedence: https://docs.python.org/3/reference/expressions.html#operator-precedence
Comparisons (i.a. chaining): https://docs.python.org/3/reference/expressions.html#not-in
All comparison operators in Python have the same precedence. In addition, Python does chained comparisons. Thus,
(a < 0 != b < 0)
breaks down as:
(a < 0) and (0 != b) and (b < 0)
If any one of these is false, the total result of the expression will be False
.
What you want to do is evaluate each condition separately, like so:
(a < 0) != (b < 0)
Other variants, from comments:
(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
You can use this
return (a < 0) != (b < 0)
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
So it becomes
(a < 0) and (0 != b) and (b < 0)
See https://docs.python.org/3/reference/expressions.html#not-in