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
.