Why the expression 1>=2==5<=4 results in False?
According to the documentation of python 3, the operators >=,==,<= have same precedence and left to right binding. As per the rule, the evaluation of the statement should be in the following manner (assuming True=1 and False=0):
1>=2==5<=4
=> False==5<=4
=> False<=4
=> True
I am unable to understand why this expression evaluated as False. I am new to python. Can anyone please help me with the understanding of this operators precedence?
As per the documentation, it's not exactly evaluated left to right. The and's are implicit
It's false because at least one (the first) condition is false, causing a short circuit evaluation
1>=2 and 2==5 and 5<=4
=> False and (doesn't matter)
=> False
Comparisons can be chained arbitrarily, e.g.,
x < y <= z is equivalent to x < y and y <= z.
1>=2==5<=4 can be written as
1>=2 and 2==5 and 5<=4
You can learn more about the comparison operators in python here.
Comparisons can be chained arbitrarily, e.g., 1 >= 2 == 5 <= 4is equivalent to 1 >= 2 and 2 == 5 and 5 <= 4 except that 2 and 5 is evaluated only once (but in 1>=2==5 case 5 is not evaluated at all when 1 >= 2 is found to be false and same in case when 2==5<=4, 4 is not evaluated at all when 2 ==5 is fount to be false).
Note that 1 >= 2 == 5 <= 4 doesn’t imply any kind of comparison between 1 and 4, and also 2 and 4.
Mark answer if helpful.
Related
Can somebody explain me why Why print(5 ** 2 ** 0 ** 1) = 5 in Python?
I am trying to learn the language and somehow I am not quite sure how this math is done.
Thank you in advance.
Because, like many languages, the exponentiation operator binds right-to-left:
5 ** 2 ** (0 ** 1)
==
5 ** (2 ** 0)
==
5 ** 1
==
5
Exponentiation is right-associative, so your expression is the same as
5 ** (2 ** (0 ** 1))
== 5 ** (2 ** 0)
== 5 ** 1
== 5
where any integer raised to the zeroth power is 1 by definition.
Others have already pointed this out already, but I just wanted to mention the documentation. You can see this by typing help("OPERATORS") in your repl. There you will spot somewhere at the top:
Operators in the same box group left to right (except for exponentiation, which groups from right to left).
You are right to be surprised though, this seems like a very odd decision to me. In other languages, e.g. octave, 5 ^ 2 ^ 0 ^ 1 == 1 as you'd expect. Oddly enough, both Julia and R agree with python on this.
EDIT: On second thought, I suppose making exponentiation right-associative makes sense too; you would expect
to mean 5^8 rather than 25^3 ...
Incidentally, here's another trap. How much is: 5 * -1 ** 2 ? Is it 5 or -5?
See help("**") to see why it is what it is. (incidentally, this is how octave, R, and julia treat this case too).
The moral of the story is: always group when there is potential for ambiguity. Or at least check the precedence is what you think it is before ungrouping.
** is exponentiation.
0 raised to the power of 1 is 0. So, we could re-write the statement as print(5**2**0) without changing the result.
2 raised to the power of 0 is 1. So, we can re-write the statement as print(5**1) without changing the result.
5 raised to the power of 1 is 5. So, we can rewrite the statement as print(5) without changing the result.
This question already has answers here:
Boolean operators vs Bitwise operators
(9 answers)
Closed 5 years ago.
Below are the different scenarios tried using '&' and 'and' conditional operators and its result. (using Python 2.7)
Using '&' operator:
Using 'and' operator:
Wondering why both conditional operators showing different behaviour?
Explanation with real scenarios would be helpful.
Thanks in advance.
& is not a conditional operator. It stands for the bitwise and. Not only it is a different operator but also the operator precedence is different (and is below > while & is above).
So first of all an example:
>>> 1 and 2
2
>>> 1 & 2
0
Now lets analyze your case:
>>> point = 1
>>> score = 2
>>> point == 1 & score > 0
Now the operator precedence kicks in and the last line is equivalent to
>>> point == (1 & score) > 0
Note that == and > have equivalent precedence. So lets evaluate that:
>>> 1 & score
0
>>> point == 0 > 0
The last line is equivalent to (point == 0) > 0 (when operators have equal precedence then you simply go from left to right). Lets evaulate that:
>>> point == 0
False
>>> False > 0
False
All in all
>>> point == 1 & score > 0
False
Can you break down the evaluation for your second statement now?
The issue is that & is not actually a logical "and", it's a bitwise operator. So it'll compare two numbers by each bit, and produce a number that has a bit set if both of the first two numbers had that bit set. So 1 & 2 will give you 0.
This wouldn't usually be a problem (True is 1, False is 0) - except that the operator precedence for & and and relative to > and = are different.
So 1 == 1 & 2 > 0 (the first case):
This is interpreted as 1 == (1 & 2) > 0, or 1 == 0 > 0, and since 1 == 0 is False the whole thing is False.
Whereas 1 == 1 and 2 > 0 (the second case):
This is interpreted as (1 == 1) and (2 > 0), and since both of those cases are True, the whole thing is True.
and tests whether both expressions are logically True while & (when used with True/False values) tests if both are True.
& is a bitwise AND operator, whereas and is a logical operator.
What does the python operator =- do? I'm not asking about the -= operator, which I realize is shorthand for x = x - value.
Actually, the operator =- does not exist. It is only = (- value). So the negative of the value.
Example:
>>> x =- 1
>>> x
-1
Why not test it?
In [11]: x = 1
In [12]: y = 2
In [13]: y=-x
In [14]: y
Out[14]: -1
As you can see it does nothing, but sets a negative value of the variable on the right hand side
There is no =- operator. Depending on the context this might be two operators, e.g. x =- y is equivalent to x = (-y) (so there are two operators: assignment and negation) or an assignment with a negative constant: x =- 1 is equivalent to x = (-1) (in this context - is not an operator, it's just a negative constant).
This question already has answers here:
Why does the expression 0 < 0 == 0 return False in Python?
(9 answers)
Closed 6 years ago.
This baffles me. Even without knowing the precedence order, one can check that the two possible ways to gather the expression would give False :
>>> (0 is 0) == 0
False
>>> 0 is (0 == 0)
False
But
>>> 0 is 0 == 0
True
How come?
You are using comparison operator chaining. The expression is interpreted as:
(0 is 0) and (0 == 0)
From the Comparisons documentation:
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).
0 is 0 is true because Python interns small integers, an implementation detail, so you get (True) and (True) producing True.
When chaining comparison operators in Python, the operators aren't actually applied to the result of the other operators, but are applied to the operands individually. That is x ? y ?? z (where ? and ?? are supposed to stand in for some comparison operators) is neither equivalent to (x ? y) ?? z nor x ? (y ?? z), but rather x ? y and y ?? z.
This is particularly useful for > and co., allowing you to write things like min < x < max and have it do what you want rather than comparing a boolean to a number (which would happen in most other languages).
In Python 2.7
When asking the interpreter the following:
(1 or 3) > 2 it returns False
Why is this? What am I effectively asking the interpreter, apparently not if either 1 or 3 is greater than two.
Similarly, asking (1 or 5) in range(2,6) also returns False
I am 100% sure it has to do with my (x or y) part of the statement, but again, why is this? I do not so much need a different way of stating something like this, as I understand I could just ask:
if x in range(2,6) or y in range(2,6):
But I was just wondering why it does not work!
Let's examine (1 or 3) > 2:
(1 or 3) is evaluated first, giving 1 (see The Peculiar Nature of and and or if you're wondering why).
1 > 2 is evaluated next, giving False.
The correct way to express what you're trying to express is:
>>> 1 > 2 or 3 > 2
True
Another, more general, way is as follows:
>>> t = (1, 3)
>>> any(el > 2 for el in t)
True
Here, t can be any iterable.
1 corresponds to true. Thus the result for
1 or 3
is
1
and
1 > 2
is false.
And you could have known this if you had tried the answer for
1 or 3
in the shell.
That's not the proper use case for boolean operations. The first should be:
(1 > 2) or (3 > 2)
The expression:
(1 or 3) > 2
will first work out 1 or 3 then attempt to figure out if that is greater than two.
Similarly:
(1 or 5) in range(2,6)
is probably better expressed as either:
(1 in range(2,6)) or (5 in range(2,6))
or:
((1 >= 2) and (1 < 6)) or ((5 >= 2) and (5 < 6))
1 (understood as number) is evalued true (all numbers are evaluated to true, except 0), so there isn't the need to evalute 3 (understood as number).
This because you use an OR condition, that "stop" evaluation onto first true value that find.
So, is 1 > 2? The answer is false
You have to decompose or if into two separate condition:
1 > 2 or 3 > 2
I'm gonna throw my two cents into this question as well.
When Python evaluates your statement
(1 or 3) > 2
This is what it does, Hey! Let's take first number and call bool() on it. Any number here that isn't 0 will be evaluated to True and return that.
You can try (10000 or 3), it will always return the most left hand "variable" as long its not 0
Example of the opposite would be if you had
(0 or 3)
It then goes on to evaluate the rest of the expression, which basically will say in pseudocode:
returned number (wheter its the left or right) is greater than 2
And this is where it gets weird, your expression will always then differ because of how the parenthesis was evaluated.
In your case it'll be
1 > 2 == False but (0 or 3) > 2 == True
As for the range part, the same logic applies.
In the parenthesis the left hand number will be "returned" and thusly, wont be available in your range check.
(1 or 4) in range(2,5) == False