简体   繁体   中英

Why this conditional does not raise an Exception: (1==0 <= 1/0) == False? How Python parses this?

How come this is evaluate to False ?

1==0 <= 1/0

First note that in Python:

bols = [False, True] for A in bols: for B in bols: print(f'{str(A):>5}, {str(B):>5}, {str(A<=B):>5}') Outputs:

False, False, True False, True, True True, False, False True, True, True If you are familiar with boolean logic this hould be natural to you.

Now it gets weird:

print(1==1 <= 1/1, 1==0 <= 1/1)

Out: True, False

And now it gets weirder:

print(1==0 <= 1/0)

Out: False

Why this last one does not throw an exeption?

My first guess is becasue of parsing issues. For example, a previous comparasion we can fix adding parenthesis:

print(1==1 <= 1/1, (1==0) <= 1/1)

Out: True, True

But if this issue is a parsing problem, how come python does not raise an exception when we divide by 0?

If we add parenthesis to the last comparasion we can force Python to raise ZeroDivision Exeption:

print((1==0) <= 1/0)

Out: ZeroDivisionError: division by zero

Also, why the following raises an Exception?

1==1 <= 1/0

Out: ZeroDivisionError: division by zero

NB: This works with other exceptions as well, probably with any, since python does not evaluate the right hand side of the inequality.

Why?

I would understand if the laizy evaluation were True , but why False ? Feels like a bug in Python.

1==0 <= 1/0

1/0 is never evaluated. The expression triggers chained comparison in Python. It is evaluated as:

(1 == 0) and (0 <= 1/0)

Logical and short-circuits when a False value is reached, so the second condition is never tested. Since 1 == 0 evaluates to False , the result is False .


1==1 <= 1/0

In the same vein, this is evaluated as:

(1 == 1) and (1 <= 1/0)

Since the first expression is True , the second one is evaluated. This leads to ZeroDivisionError .


(1==0) <= 1/0

Parentheses have higher priority than comparison operators. So chained comparisons are not triggered here. The expression is evaluated as False <= 1/0 . Of course, the comparison will fail with ZeroDivisionError .


1==1 <= 1/1, 1==0 <= 1/1

Here you are defining a tuple of results. A tuple is implicit by the existence of a comma separating your two expressions. The first, 1==1 <= 1/1 , evaluates to True since True <= 1 . The second, 1==0 <= 1/1 , evaluates to True since False <= 1 .

These comparisons work since bool is a subclass of int , so True is equivalent to 1 and False is equivalent to 0 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM