Python precedence rules for boolean operators [duplicate] - python

This question already has answers here:
Priority of the logical operators (order of operations) for NOT, AND, OR in Python
(8 answers)
Closed 6 years ago.
When I evaluate the following expression:
1 or (1/0) and 1
What are the rules (precedence, short-circuit evaluation etc) are followed to get the answer

b or anything_else is defined to return b if b is true-ish, without evaluating anything_else. Since your first 1 is true-ish, your 1/0 never gets evaluated, hence no error. By "true-ish" I mean any value that Python considers true, not only the True boolean value. Try your expression with True or [2] in place of the first 1 to see what I mean.

Python short-circuit evaluates. In your example, the expression
1 or (1/0) and 1
finishes evaluation at the first 1 and returns True.
A more minimal example serves to illustrate Python's short-circuit evaluation. Consider the expression:
(1/0) or 1
This raises a ZeroDivisionError exception upon evaluation of (1/0). But the expression:
1 or (1/0)
short-circuit evaluates to True. No exception is raised since the sub-expression (1/0) never gets evaluated.

Related

Argument evaluation order [duplicate]

This question already has answers here:
Is Python's order of evaluation of function arguments and operands deterministic (+ where is it documented)?
(2 answers)
Closed 4 months ago.
Is the python argument evaluation order defined behaviour? And is the order of evaluation the same as the appear in the source-code?
Consider this example:
print(f"{(a:=1)}", f"{a=}", f"{(a:=2)}", f"{a=}") # print 1
print(f"{a=}") # print 2
Is the first statement guaranteed to print "1 a=1 2 a=2"?
And is the second guaranteed to print "a=2"?
Yes, python expressions are evaluated left to right. This is documented here.

For NOT, when to use ~ or NOT? [duplicate]

This question already has answers here:
The tilde operator in Python
(9 answers)
Closed 1 year ago.
I'd like to check if a dataframe is empty or not. use ~df.empty return -2 while using Not df.empty return False.
why I cannot use ~?
df.empty
True
~df.empty
-2
not df.empty
False
In Python ~ is the bitwise not operator, it takes the bits and swaps 1s and 0s. For boolean values, true is 0b00000001 and false is 0b00000000 so ~true is 0b11111110 which, since bool a special case one byte int, evaluates as the signed integer value -2.
not on the other hand is the logical not operator, if a value is true/truthy it returns false, if a value is false/falsy it returns true, it doesn't care about the specific bits, only that (generally) at least one of the bits is 1.
Operation
True0b00000001
False0b00000000
~
-20b11111110
-10b11111111
not
False0b00000000
True0b00000001

Using AND inside abs(number) in Python

Trying to understand how AND statement works inside abs(numbers) function.
Calling print(abs(21-22 and 9-4 and 11-8))
This would always give me whatever the last expression is. In this case it calculates 11-8, so it prints 3.
Why other expressions are not in the output and no error as well?
The fact that the expression is inside an abs call doesn't change the way that it's interpreted:
>>> 21-22 and 9-4 and 11-8
3
which is of course the same as:
>>> -1 and 5 and 3
3
An and evaluates the "truthiness" of each operand. If either of them is "falsey", that one is returned; otherwise the last one is returned.
All int values except 0 are "truthy", so the only time you'll get something other than the last value from an and of ints is if one of them is zero:
>>> -1 and 0 and 3
0
and is a logical operator, it will return True if both the operands of the operator are true. I believe the comma does what you expected to do in this case:
print(abs(21-22),abs(9-4),abs(11-8))

Zero Division Error in boolean statement Python [duplicate]

This question already has answers here:
Does Python evaluate if's conditions lazily? [duplicate]
(7 answers)
Closed 4 years ago.
print(True or 5 / 0 > 3)
This is my code but it returns True
Is there a reason why it doesn't return a Zero Division Error?
Its because True is always true. The Python interpreter does not evaluate the right side of the or operator in this case, because the outcome of an or expression is always true if one of its operands is true. If you enter5 / 0 > 3 or True than you get your devision by zero error

"4 and 5" is 5, while "4 or 5" is 4. Is there any reason? [duplicate]

This question already has answers here:
Does Python support short-circuiting?
(3 answers)
How do "and" and "or" act with non-boolean values?
(8 answers)
Closed 9 years ago.
When I test the difference between and and or, I meet this problem. Could you please help me understand it?
This behavior is a weird quirk that comes out of three different features of python code. Non-zeros values are true, logical operation evaluation, and short-circuiting. I'll explain these features below:
Non-Zero Values are True
The first thing you have to know in evaluating these expressions is that they are logical operators. They are designed to work with true or false values:
true and true = true
true and false = false
false and true = false
false and false = false
true or true = true
true or false = true
false or true = true
false or false = false
However, python (and many languages) allow you to put any value in. So long as they are non-zero they are considered true. So:
4 and 5 = true
4 and 0 = false
This is normal so far. Most languages have this.
Logical Operation Evaluation
Here Python does something a little unique. Instead of returning true or false, it actually returns the value of the last item it checked in the statement. So:
4 and 5 = 5 (which will be evaluated as true)
To fully understand which value will actually get returned you have to also understand:
Short-Circuiting
When evaluating these logical operators, the compiler can often stop early. Take the example:
3 or 4
We know that the statement will return true, but which value will it return? To figure this out you have to understand which value will be the last one looked at. The system will look at 3, and realize that the statement is true. It doesn't matter what the second value is, 3 or anything is true. So the value returned is 3 because it is the last value checked.
However, if we use and:
3 and 4
Once we look at 3, we still need to check that the second value is true. It could makes a difference. So the second value is evaluated. If it is true, it returns the last value looked at, in this case 4.
In Conclusion
You just have to think about which value the interpreter can stop on.
3 or 4 = 3 // because we can stop at 3
3 and 4 = 4 // because we have to check the 4
0 or 3 = 3 // because we needed to check the 3
Yes, the and operator requires all arguments to be true, and returns the last one checked, which is 5. (If any of the arguments were false, it would return the first false value, since that would be the last one checked in order to verify if all arguments were true.)
The or operator requires only one argument to be true, and returns the last one checked, which is 4, because 4 represents the first true value in the conditional. (If all arguments were false, then the return value would be equal to the last false value, since that would be the last value checked in order to verify if any of the arguments were true.)
true1 and true2 >>>true2
true1 or true2 >>>true1
when runinng true1 and true2, python must check the value returned by every expression is true or not, so it will return the last one.
but when running true1 or true2 , as true1 retrun "true" (in your example, 4 is "true") already, so it is unncessary to continue checking the rest.
I think the way to look at it is at a simpler level, which was designed for optimization.
and requires that both sides be "truthy." It checks the left side. If it is "truthy," it returns the second value without checking what it is.
or requires only one side to be "truthy." It checks the first side. If it is "truthy," it returns it. If not, it returns the second side, again without checking it.
For "4 and 5", because 4 is "truthy," it returns 5.
For "4 or 5", it returns 4 without even looking at 5.
Need proof? Make these functions:
def four():
print 'Evaluating four!'
return 4
def five():
print 'Evaluating five!'
return 5
Now see what gets printed:
>>> four() and five()
Evaluating four!
Evaluating five!
5
and evaluated four(), and since it was true it returned five().
>>> left() or right()
Evaluating left side!
4
or evaluated four() and since it was true, returned four() without even calling five()!

Categories

Resources