站点图标 AI技术聚合

Is python broken in my computer or am I missing how this should work? [duplicate]

问题描述:

Recently I was solving one of the very basic problems on conditionals from Hackerrank.

The problem was:

If n is odd, print Weird
If n is even and in the inclusive range of 2 to 5 print Not Weird
If n is even and in the inclusive range of 6 to 20 print Weird
If n is even and greater than 20, print Not Weird

So i wrote the following code

if(n % 2 == 0 & n >=6 & n <= 20 ):
    print("Weird")
elif(n % 2 == 0 & n <= 2 & n >= 5): 
     print("Not Weird")
elif( n % 2 != 0):
     print("Weird")
else:
     print("Not Weird")

It didn’t work at first. I figured out that i had to use “and” instead of “&”.
But, I am not convinced why did this happen..
for n = 12, all 3 conditions of the first if condition are true. so true & true & true should also be true, right?

this photo shows the code snippet with some print messages

I am very intrigued to know the reason behind this behaviour, please guide! (may be something very minor but please don’t mind :) )

解决方案 1[最佳方案][1]

Every time you have this kind of doubts, you can use the dis module, in your case I make a lambda function to evaluate the process:

func = lambda x: x % 2 == 0 & x >= 6 & x <= 20

this gives us the follow disassmbled code:

              0 LOAD_FAST                0 (x)
              2 LOAD_CONST               1 (2)
              4 BINARY_MODULO
              6 LOAD_CONST               2 (0)
              8 LOAD_FAST                0 (x)
             10 BINARY_AND
             12 DUP_TOP
             14 ROT_THREE
             16 COMPARE_OP               2 (==)
             18 JUMP_IF_FALSE_OR_POP    40
             20 LOAD_CONST               3 (6)
             22 LOAD_FAST                0 (x)
             24 BINARY_AND
             26 DUP_TOP
             28 ROT_THREE
             30 COMPARE_OP               5 (>=)
             32 JUMP_IF_FALSE_OR_POP    40
             34 LOAD_CONST               4 (20)
             36 COMPARE_OP               1 (<=)
             38 RETURN_VALUE
        >>   40 ROT_TWO
             42 POP_TOP
             44 RETURN_VALUE

explained is just:

Of course, this is the bytecode explanation of how python works, the short answer is the 0 & n >= 6 & n thing, with this in mind, we can assume than every number different from 0, will return False to this evaluation, because a bitwise operation between b'0110' will always be greater than 0.

TL;DR

Bitwise operators are evaluated before Boolean operators.

References

https://docs.python.org/3.8/library/dis.html Dis module reference.

解决方案 2:[2]

for n = 12, all 3 conditions of the first if condition are true.

>>> n = 12
>>> n % 2 == 0 & n >= 6 & n <= 20
False

The second condition is false (and the conditions aren’t what you think they are, because bitwise operators are similar to other numeric operators [+, -, %, etc] in that they have higher precedence than comparison operators).

Let’s break this down a little:

>>> n % 2
0
>>> 0 & n
0
>>> 6 & n
4
>>> 0 == 0 >= 4 <= 20
False

The expression is false because of the 0 & n >= 6 & n condition. 0 isn’t greater than 4!

解决方案 3:[3]

It may not be immediately obvious from the grammar, but binary arithmetic operations bind tighter than binary bitwise operations. So your comparison is the same as

>>> if(n % 2 == (0 & n) >= (6 & n) <= 20 ):
...     print("Weird")
... 
>>>

Your “true & true &true” case is

>>> if((n % 2 == 0) & (n >=6) & (n <= 20) ):
...     print('Weird')
... 
Weird

But that only works because python True and False evaluate to 1 and 0. A bitwise operation only works because of this underlying representation.

参考链接:

Copyright Notice: This article follows StackOverflow’s copyright notice requirements and is licensed under CC BY-SA 3.0.

Article Source: StackOverflow

[1] Erick IO

[2] Samwise

[3] tdelaney

退出移动版