Reputation: 11
a=True and 1/0
print(a)
The output for the above code fragment shows an error.
While the output for the below code fragment :
a=False and 1/0
print(a)
Is False
Why is that so? From the layman point of view, since 1/0 is undefined, error should be displayed in each case.
Similarly if I take a = True or 1/0, output is true while an error for False or 1/0
I tried different versions of this:
a=1/0 or False
print(a)
or
a=1/0 or True
print(a)
Both of which display an error (division by zero)
I realized that it has something to do with the order I take them in and the boolean operators I use.
In any case, why am I getting an output and in some cases?
Upvotes: 0
Views: 128
Reputation: 81
and
operator stops when a False
is encountered to save resources.
Here:
a=False and 1/0
Division is never computed.
The same you can check with or
operator: it stops when True
is validated:
a=True or 1/0
Will give True
.
Upvotes: 1
Reputation: 70367
Python exhibits short-circuit evaluation semantics for and
and or
expressions. What that means is that, if the result of the entire expression can be determined from the left-hand-side, then the right-hand-side needn't be evaluated.
False and a
Here, we first evaluate the expression False
(which is a literal and equal to the Python value False
). Now, and
is only true if both sides are true, and we've already found one side which is false. So no matter what a
evaluates to, the result is False
. Hence, we don't evaluate the right-hand-side because it's unnecessary.
Likewise,
True or a
Since True
is truthy and or
only requires one of its arguments to be truthy, whatever a
evaluates to, the result is True
.
This is commonly used to do several veins of error checking in one line. Python doesn't have a null-safe access operator, so we can do the next best thing.
if person is not None and person.salary is not None:
...
Without short-circuit evaluation, the person.salary is not None
would evaluate, even in the case where person
is actually None
, which is an error. We'd have to write the more verbose
if person is not None:
if person.salary is not None:
...
which does nothing for readability.
Likewise, we can use or
to short circuit error conditions.
if person is None or person.salary is None:
raise(MyCustomException("This person doesn't have a job"))
Again, if person
happens to be None
, we don't want person.salary
to evaluate at all, or we'll get an AttributeError
rather than our nice, informative custom exception. Without short-circuiting, we'd have to resort to the much uglier
if person is None:
raise(MyCustomException("This person doesn't have a job"))
if person.salary is None:
raise(MyCustomException("This person doesn't have a job"))
Upvotes: 2
Reputation: 106
In case of False
, It is not necessary to check more after and
- it is due to the optimization, so 1/0
is never executed.
On the other hand: a=1/0 and False
will not work as 1/0
is evaluated first.
Upvotes: 1
Reputation: 21757
Both and
and or
are short circuited i.e. if the first input is respectively false or true, the rest of the inputs are not evaluated at all. That is why both False and 1/0
as well as True or 1/0
can return results, while other variations do not.
Upvotes: 2