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

was learning bitwise operators in python until i get to this. print(True & True) output is True print(10<20) output is True again. Now when I do this: print(10<20 & 10<20) the output ...

问题描述:

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:

  • Get var x value
  • Get const 2 value
  • Get modulo comparison between 2 and x, the answer is 0 when you use 12 as the param value.
  • Get const 0 value
  • Get var x value
  • Get Binary and comparison between 0 and x, naturally, a bitwise operation between any value (eg: b'1100') and b'0000' will return 0.
  • Next, values are stored in TOP and compared with == operator. This means as other answers said (x % 2) == (0 & x) at this time, with x being 12, the translated operation is 0 == 0 (True).
  • With the == result check if is False (in that case, jump to row 40 of bytecode) else, remove the result (POP) from TOS (Top of stack)
  • Get const 6 value
  • Get var x value
  • Another and comparison, this time between 6 (b'0110') and 12 (x = b'1100') with a result of 4 (b'0100')
  • The last result is stored in TOP and compared with >= operator with the last stored value (0 >= 4 as said in other answers).
  • Response from 0 >= 4 is then, evaluated in the next instruction, False causes than the code skip directly to the instruction 40 (Return False) without even test the last case.

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

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2023年12月22日
下一篇 2022年5月7日

相关推荐