0 is 0 == 0 (#evaluates to True?) [duplicate] - python

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).

Related

True & False is giving True in Python. Why? [duplicate]

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.

Comparison Operator Precedence and Binding

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.

How can an expression be different from however paarenthesized? [duplicate]

This question already has answers here:
Why does the expression 0 < 0 == 0 return False in Python?
(9 answers)
python operator precedence of in and comparison [duplicate]
(3 answers)
Closed 5 years ago.
Consider this statement:
> False == False in [False]
True
However:
> (False == False) in [False]
False
> False == (False in [False])
False
It is incredible. What's the reason and the interpretation?
dis.dis to the rescue and a bit of my interpretation.
Anyway, it looks like this. Consider three expression X, Y, Z and two operators O1, O2. Then
X O1 Y O2 Z
is equivalent to
(X O1 Y) and (Y O2 Z)
as can be seen by
a < b < c
example. I find this behaviour very counterintuitive.
And the docs:
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).
Note that in is a comparison operator.

What does the python operator =- do?

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).

Could someone explain the logic here or what I am asking? (Boolean operations)

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

Categories

Resources