Python order of operations involving "in" and "==" [duplicate] - python

This question already has an answer here:
Why does (1 in [1,0] == True) evaluate to False?
(1 answer)
Closed 4 years ago.
I noticed the following strange behavior:
'a' in 'a' == True # Returns False
('a' in 'a') == True # Returns True
'a' in ('a' == True) # throws TypeError
How is the first expression parsed? Both placements of parentheses yield different results.
(Python 3.6)

From the docs:
Note that comparisons, membership tests, and identity tests, all have the same precedence and have a left-to-right chaining feature as described in the Comparisons section.
in and == are membership and comparison operators respectively.
From Comparisons:
... expressions like a < b < c have the interpretation that is conventional in mathematics:
[...]
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).

Related

Confusion related to Python's `in` operator [duplicate]

This question already has answers here:
Unexpected result from `in` operator - Python [duplicate]
(3 answers)
Closed 2 years ago.
I found strange behavior with Python's in operator
d = {}
'k' in d == False # False!
I thought it's because of precedence:
('k' in d) == False # True, it's okay
'k' in (d == False) # Error, it's also okay
But, what precedence evaluates the following expression then?
d = {}
'k' in d == False
If it's because of wrong precedence why it doesn't fire an error like if:
'k' in (d == False)
In other words, what happens under the hood of Python with this expression?
'k' in d == False
in is considered a comparison operator, and so it is subject to comparison chaining.
'k' in d == False
is equivalent to
'k' in d and d == False
because both in and == are comparison operators.
You virtually never need direct comparison to Boolean literals, though. The "correct" expression here is 'k' not in d.
For reference, this is described in the Python documentation, under 6.10. Comparisons:
comparison ::= or_expr (comp_operator or_expr)*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="
| "is" ["not"] | ["not"] "in"
and
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).

Why does this boolean expression evaluate to False? [duplicate]

This question already has answers here:
python operator precedence of in and comparison [duplicate]
(3 answers)
Closed 3 years ago.
Can someone explain to me why the Python interpreter evaluates this expression to be False?
1 in [1] == True
I would expect that 1 in [1] would evaluate to True, and obviously True == True would be True. However this isn't what happens - the expression is False. Why does this happen?
== and in are both comparison operators. And when you have multiple comparison operators like this, Python considers it a chained comparison. For example, 1 < x < 10 is equivalent to 1 < x and x < 10.
In your case, 1 in [1] == True is equivalent to (1 in [1]) and ([1] == True), which evaluates to False.
If you have an expression like this python split it to more statements. In fact:
1 in [1] == True equals to: (1 in [1]) and ([1] == True)
Right side is false since [1] != True and whole sentence is false

Why this statement is evaluated to False even it is true? [duplicate]

This question already has answers here:
python operator precedence of in and comparison [duplicate]
(3 answers)
Closed 3 years ago.
I started learning python but I've noticed something unsual, something that I do not understand, why the expression provided below it's evaluated to false even it is true??
l = [1,2,3,4,5,"Hi"]
"Hi" in l # returns True
"Hi" in l == True # returns False
"Hi" in l == True is evaluated as ("Hi" in l) and (l == True) which is False.
Explanation from documentation:
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent
to x < y and y <= z

Boolean comparison in python [duplicate]

This question already has answers here:
Check if a word exists in a dictionary doesn't find any word
(1 answer)
Is `a<b<c` valid python?
(2 answers)
Closed 5 years ago.
Python seems to evaluate oddly with (what I thought) would be relatively straightforward syntax. Can anyone shed light on what's happening behind the scenes here? What does python think is happening in the first case?
>>> x = 'foo'
>>> 'f' in x == True
False
>>> ('f' in x) == True
True
>>> 'f' in (x == True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argument of type 'bool' is not iterable
What you see here is chained comparisons:
'f' in x == True
Both in and == are both comparisons. Now Python interprets chained comparison interpreters with an implicit and. So you have basically written:
'f' in x and x == True
and the second check fails.
The same occurs if you for instance write:
a < b in c
it is short for:
a < b and b in c
(except that expressions are only evaluated once).
If we take a look at the documentation, we see that there are 11 comparators:
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
| "is" ["not"] | ["not"] "in"
and furthermore it states:
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).
Formally, if a, b, c, ..., y, z are expressions and op1,
op2, ..., opN are comparison operators, then a op1 b op2 c ... y
opN z is equivalent to a op1 b and b op2 c and ... y opN z, except
that each expression is evaluated at most once.

When checking if an item does not exist in a list, why doesn't this code work - if item in list == False: [duplicate]

This question already has answers here:
python operator precedence of in and comparison [duplicate]
(3 answers)
Closed 9 years ago.
Consider this list:
list = [1,2,3,4,5]
I want to check if the number 9 is not present in this list. There are 2 ways to do this.
Method 1: This method works!
if not 9 in list: print "9 is not present in list"
Method 2: This method does not work.
if 9 in list == False: print "9 is not present in list"
Can someone please explain why method 2 does not work?
This is due to comparison operator chaining. From the 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).
You are assuming that the 9 in list == False expression is executed as (9 in list) == False but that is not the case.
Instead, python evaluates that as (9 in list) and (list == False) instead, and the latter part is never True.
You really want to use the not in operator, and avoid naming your variables list:
if 9 not in lst:
It should be:
if (9 in list) == False: print "9 is not present in list"

Categories

Resources