This question already has answers here:
python operator precedence of in and comparison [duplicate]
(3 answers)
Closed 2 years ago.
Suppose I have the following line of code:
print("valley" in "hillside" == False)
Since the precedence of in and == is equivalent in Python, I expected the operations to be performed from left to right, producing True as the output.
However, in actuality, when I run this line of code, I get False.
I have noticed that adding brackets around "valley" in "hillside" results in True as the output but I don't seem to understand why it's necessary in the first place...
Both in and == are comparison operators, so the parser treats
print("valley" in "hillside" == False)
the same as
print("valley" in "hillside" and "hillside" == False)
See the section on Comparisons in the Python language reference for more details, in particular this note:
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
print 1>0 == (-1)<0 # => False
print (1>0) == ((-1)<0) # => True
First line prints False.
Second line prints True
The problem is if according to the order comparison operators are above equality operators.
Shouldn't both lines print True? (Or at least the same thing..)
https://www.codecademy.com/en/forum_questions/512cd091ffeb9e603b005713
Both equality and the greater than and less than operators have the same precedence in Python. But you're seeing something odd because of how an expression with multiple comparison operators in a row gets evaluated. Rather than comparing the results of previous calculations using its rules of precedence, Python chains them together with and (repeating the middle subexpressions).
The expression 1 > 0 == -1 < 0 is equivalent to (1 > 0) and (0 == -1) and (-1 < 0) (except that each of the repeated subexpressions, like -1 only gets evaluated once, which might matter if it was a function call with side effects rather than an integer literal). Since the middle subexpression is False, the whole thing is False.
In the second version, the parentheses prevent the comparison chaining from happening, so it just evaluates the inequalities independently and then compares True == True which is True.
I am learning about Python operators and following code snippet leaves a doubt.
I've learnt so far that:
AND operator which is a logical operator returns True if both the operands are true.
& operator which is a bitwise operator returns 1 if both the bits are 1 else 0.
But following code snippet is little bit confusing as it seems like it checks whether the both the operands are true, but if so it should result False.
x = 4
y = -1
print("answer: ",x == y & x >=y)
output:
answer: True
Can someone please help me to understand the code.
Thanks in advance!
I think it's because the & operator has a higher priority, so y&x evaluates first and yeilds 4. This then evaluates true for both and returns true:
Your Code:
x = 4
y = -1
print("answer: ",x == y & x >=y) # becomes 4(x) == 4(x&y) >=-1(y), so it is True
# The variable is in brackets after its value
Output:
answer: True
Changed code:
x = 4
y = -1
print(y&x)
print("answer: ",(x == y) & (x >=y))# This should help
Output:
4
answer: False
The term you're looking for is operator precedence. Bitwise and happens before comparisons.
https://www.programiz.com/python-programming/precedence-associativity
Your expression is evaluated as
x == (y & x) and (y & x) >= y
Note that the & operator is bitwise and, not logical and. You wouldn't run into this issue if you used the logical and because comparison precedes logical operations
Currently your code is first calculating (y&x) which is equal to 4 and then this is equated to x which is also 4. After that 4>=y is being finally done. which is also true. This is the reason why your output is true. Try adding brackets to do calculation according to your method.
Like here:
Instead of x == y & x >=y , this should be written (x == y) & (x >=y)).
This question already has answers here:
What does it mean that Python comparison operators chain/group left to right?
(2 answers)
Why does the expression 0 < 0 == 0 return False in Python?
(9 answers)
Where in the python docs does it allow the `in` operator to be chained?
(1 answer)
Closed 5 years ago.
I just stumbled upon the following line in Python 3.
1 in range(2) == True
I was expecting this to be True since 1 in range(2) is True and True == True is True.
But this outputs False. So it does not mean the same as (1 in range(2)) == True. Furthermore it does not mean the same as 1 in (range(2) == True) which raises an error.
Despite years of experience in Python, I am taken off guard. What is going on?
This is due to the fact that both operators are comparison operators, so it is being interpreted as operator chaining:
https://docs.python.org/3.6/reference/expressions.html#comparisons
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 is equivalent to:
>>> (1 in range(2)) and (range(2) == True)
False
print 1>0 == (-1)<0 # => False
print (1>0) == ((-1)<0) # => True
First line prints False.
Second line prints True
The problem is if according to the order comparison operators are above equality operators.
Shouldn't both lines print True? (Or at least the same thing..)
https://www.codecademy.com/en/forum_questions/512cd091ffeb9e603b005713
Both equality and the greater than and less than operators have the same precedence in Python. But you're seeing something odd because of how an expression with multiple comparison operators in a row gets evaluated. Rather than comparing the results of previous calculations using its rules of precedence, Python chains them together with and (repeating the middle subexpressions).
The expression 1 > 0 == -1 < 0 is equivalent to (1 > 0) and (0 == -1) and (-1 < 0) (except that each of the repeated subexpressions, like -1 only gets evaluated once, which might matter if it was a function call with side effects rather than an integer literal). Since the middle subexpression is False, the whole thing is False.
In the second version, the parentheses prevent the comparison chaining from happening, so it just evaluates the inequalities independently and then compares True == True which is True.
I want to write this if statement as compact as possible (to avoid having duplicate code)
if length == 10 if boolean is False or length == 13 if boolean is True:
The part that PyCharm does not like is the
if boolean is True
It asks for a colon.
PyCharm does not allow me to run it. Does anyone have a nice compact solution to this if?
I think you meant
if (not boolean and length == 10) or (boolean and length == 13):
The parentheses aren't necessary, but I think they help readability. #jonsharpe's solution is even shorter and only has to evaluate boolean once, but it may be harder to read, especially if you're not familiar with Python's ternary expressions.
Never use is for equality comparison (that's what == is for), but boolean types should never be explicitly compared to True or False anyway.
You can use a conditional expression (also known as a "ternary") to write it out much more concisely:
if length == 13 if boolean else length == 10:
or, equivalently:
if length == (13 if boolean else 10):
Per the documentation:
The expression x if C else y first evaluates the condition, C (not x); if C is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned.