Quirky output python - python

Please explain below, I think it should have printed True or False since these are boolean expressions. And why it's printing 2 1 and then 1 2
print 1 and 2
print 2 and 1
print 1 or 2
print 2 or 1
output:
2
1
1
2

Why you think the result must be a boolean type ?
from python wiki :
The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.
The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.
Note that neither and nor or restrict the value and type they return to False and True, but rather return the last evaluated argument. This is sometimes useful, e.g., if s is a string that should be replaced by a default value if it is empty, the expression s or 'foo' yields the desired value. Because not has to invent a value anyway, it does not bother to return a value of the same type as its argument, so e.g., not 'foo' yields False, not ''.

Related

Booleans with numbers in Python

I came across this implementation of gcd in Python:
def gcd(x,y): return y and gcd(y, x % y) or x
What I don't understand is how the boolean is working in the return? After trying some numbers in the interpreter I noticed that and always returns the number on the right, while or returns the number on the left. Why is this? Also, can you walk me step by step through a simple call of this function so I can understand what is happening?
This is because of how and and or operators evaluate in Python.
From documentation -
The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.
The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.
They do not return True or False , they return the last evaluated value , and that is why we can write things like -
s = s or "Some default value"
To default the value of s if its None or empty string or empty list, or 0.
Basically, or returns the first non false-like value ( where false-like values are 0, or None or Empty string/list/tuple, etc ) Or the last false-like value if all the values are false-like. Example -
In [1]: 0 or 10
Out[1]: 10
In [2]: 5 or 0 or 10
Out[2]: 5
In [7]: 0 or '' or [] or ()
Out[7]: ()
And, and returns the first false-like value, or the last true-like value , if all the values are true-like. Example -
In [3]: 0 and 10
Out[3]: 0
In [4]: 5 and 10
Out[4]: 10
In [6]: 5 and 0 and 10
Out[6]: 0
In your case, it works as -
if y is 0 it returns x (irrespective of the value of x) .
otherwise it computes gcd(y, x%y) if that is non-zero returns it. (Though it would never really be 0)
if the result of gcd(y, x%y) is 0, then it returns x .
This is called "short circuiting." Whenever Python knows what the result of a boolean expression is going to be, it stops evaluating. This is an optimization, but it also makes for some handy idioms, like assigning default values.
def do_a_thing(maybelist=None):
# this is done all the time when you want the default argument to be
# a list, but you don't want to make the mistake of a mutable default argument
maybelist = maybelist or []
The implementation example you gave is confusing to someone who doesn't know about Euclid's Algorithm for calculating gcd's, because it's not obvious how the heck it actually calculates the gcd. I would say that that is an example of someone abusing short circuit evaluation.
In Python, the only integer that defaults to False is zero. Logical values perform short-circuiting, as one of the comments say.
With the statement:
a and b
If 'a' evaluates to False, then 'b' does not need to be evaluated, so the result of the expression is 'a', but if 'a' evaluates to True, then b still needs to be evaluated, so b will be the result of the expression unless a evaluates to False.
`or' works the other way around, which makes sense if you think about it.
and and or are not strictly Boolean operators in Python. x and y and x or y will always evaluate to either x or y, depending on the "truthiness" of the value. False values are numerical zeros, empty strings, and empty containers; all other values are true. This means that
x and y == x if x is false; y is not evaluated
x and y == y if x is true
x or y == x if x is true; y is not evaluated
x or y == y if x is false
The only time either evaluates to an actual Boolean value is when the x or y value involved is an actual Boolean value.

Trying to understand a simple feature about 'and' command in python. Can anyone clarify it? [duplicate]

This question already has answers here:
and / or operators return value [duplicate]
(4 answers)
What does "variable or 0" mean in python?
(4 answers)
Closed 7 years ago.
In Python, if I write
z = 1 and 2
print z
Then it yields "2".
But if I write
z = 0 and 2
print z
Now, it yields "0".
It may not be much important in real life problem, but I'm trying to understand the logic here.
0, [], "" are all false-ish (they are treated as False in a python condition). and returns the first false-ish value or the last one. This is called short-circuit evaluation. That's why in one case it returns 2 (the last) and in the other it returns 0 (the false-ish).
In fact if you think about the logic operation, you can short-circuit this behaviour:
x and y (with x false-ish) -> x
x and y (with x true-ish) -> y
When plugged into a condition it will evaluate as:
In the first case it evaluates the boolean result of x which is False. This is the correct result for the and operation, since False and y = False for any y.
In the second case it evaluates the boolean value of y. Since x is True, the result of and should be False when y is False and True when y is True (it reflects the value of y).
c = a and b
is the same as
if a:
c=b
else:
c=a
I think more interesting is or:
c = a or b
is the same as
if a:
c=a
else:
c=b
Note also that if a: is a short way of if bool(a):. bool returns False for this objects/values:
None, 0, False, "", [], tuple(), dict(), set()
As you can see, they are all somehow empty...
The and operator in python short circuits. That is: it only evaluates enough operands (from left to right) as are necessary to determine whether the outcome is True or False. The result of and is False so in the second case, where 0 evaluates to False, and returns 0, but as 1 is True, the second operand must also be evaluated and returned.
0 is treated as False and anything above zero is treated as True so z = 1 and 2 sets z equal to 2 and z = 0 and 2 is 0 because it evaluates to False.

Why do I get 0 when I run "0 and True" or "0 and False"

consider this code:
>>> 0 and True
0
>>> 0 and False
0
Why do I get 0 when I run the above commands in Python?
When the first condition of an and evaluates to False (which 0 does in Python), the second argument is not evaluated at all, because the and will never become true. This is called short-circuiting. In that case, the result of the expression is the first operand, in your case 0.
Because 0 is a false value (all numeric 0 values are, as well as empty containers, and None and False).
The and operator short-curcuits; if the left-hand expression evaluates to a false value, it is returned, otherwise the right-hand expression outcome is returned.
The or operator does the same, but for a true left-hand value; 1 or False returns 1.
From the Boolean operations documentation:
The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.
The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.
You can make handy use of this:
foo = None
if something_or_other:
foo = lambda arg: arg * 3
outcome = foo and foo('bar')
outcome = foo or expensive_call()
where foo is only called if it is actually defined and not still None; the expensive_call() is only invoked if foo is not yet bound to a true value.
You are ANDing with zero. You should get zero always.
this is because, logical operators are evaluated from left to right. So, for or if True find rest of the expression not evaluated:
>>> True or "one"
True
>>> False or "one"
'one'
Similarly for and, if False found rest of the expression ignored:
>>> True and "one"
'one'
>>> False and "one"
False
In compiler design, this concept is called short-circuiting and this is same design for most of compilers.
most of programming languages have this feature, it's fast branch detection, in your case and if first condition is false, evaluation is fail and second (other) condition never check
in other case or if first condition return true second (other) condition never check and result will be true
it's really cool feature look this sample for example:
if( list != null and !list.isEmpty() ) {
// do stuff
}
if this feature does not exists this if statement cause exception, but now !list.isEmpty() will never runs when list is null

Python: what is the operation that returns 6 for the expression (2 and 2*3)?

My first question is what is the more abstract question for the question: 'what is the operation that returns 6 for the expression (2 and 2*3)? Please feel free to retitle my question appropriately.
My second question is what is it that is going on in python that returns 6 for (2 and 2*3). There seems something elegant going on here, and I'd like to read up on this operation.
From the Python language reference:
Note that neither and nor or restrict the value and type they return to False and True, but rather return the last evaluated argument.
As such, 2 and 2*3 means it first evaluates bool(2), which evaluates to True, and then it evaluates bool(2*3) which evaluates to True. Therefore it'll return the last evaluated argument, which is 2*3 (6).
According to the python docs
x and y : if x is false, then x, else y
First you have to read this and then you have to read this. :)
After that you will know that and is a boolean operator, that tries to convert it's first operand to boolean. So if you read the first thing you will see that 2 is converted to True.
The third thing you need to know is that the and operand will return it's first argument if it is converted to False and it's second argument if it evaluates to True.
So basically
z = x and y
Can be translated to:
if x:
z = y
else:
z = x
And now you understand everything. :)
2 is evaluated to True and then and operator returns the value of it's second argument which is 6.
Applying lazy evaluation, python return for a and b a if a evaluates to False and b if a evaluates to True.
Hence 2 evaluates to True, 2 and 2*3 return 2*3 which equals 6.
Basically it's same as 2 and 6.
How it works? and returns first element if it's considered False (False, 0, [] ...) and return second otherwise
This is to do with how Python evaluates the expression x and y. It returns y if x is True, and x if x if False.
So, in case of 2 and 2 * 3, since 2 is evaluated to True, it would return the value 2 * 3, which is 6.
In case of and operation between multiple operands, it returns the 1st non-True value, and if all the values are True, it returns the last value.
Similarly, for or operator, the expression say, A or B or C, returns the 1st True value. And if all the values are False, it returns the last value.

Python "and" operator with ints

What is the explanation for this behavior in Python?
a = 10
b = 20
a and b # 20
b and a # 10
a and b evaluates to 20, while b and a evaluates to 10. Are positive ints equivalent to True? Why does it evaluate to the second value? Because it is second?
The documentation explains this quite well:
The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.
And similarly for or which will probably be the next question on your lips.
The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.
See the docs:
x and y if x is false, then x, else y
non-zero integers are treated as boolean true, so you get exactly the behavior described in the docs:
>>> a = 10
>>> b = 20
>>> a and b
20
>>> b and a
10
In python everything that is not None, 0, False, "", [], (), {} is True
a and b is readed as True and True in this case
the same for b and a
and yes in this case it takes the first value
edit: incomplete as in the comments

Categories

Resources