我在其他人的代码中发现了这个奇怪的if
语句:
if variable & 1 == 0:
我不明白。它应该有两个==
,对吗?
有人可以解释一下吗?
答案 0 :(得分:33)
条件是bitwise operator比较:
>>> 1 & 1
1
>>> 0 & 1
0
>>> a = 1
>>> a & 1 == 0
False
>>> b = 0
>>> b & 1 == 0
True
正如许多评论所说,对于整数,这个条件对于平均而言是真的而对于赔率是假的。写这篇文章的流行方式是if variable % 2 == 0:
或if not variable % 2:
使用timeit
,我们可以看到效果没有太大差异。
<强> n & 1
强> ("== 0" and "not")
>>> timeit.Timer("bitwiseIsEven(1)", "def bitwiseIsEven(n): return n & 1 == 0").repeat(4, 10**6)
[0.2037370204925537, 0.20333600044250488, 0.2028651237487793, 0.20192503929138184]
>>> timeit.Timer("bitwiseIsEven(1)", "def bitwiseIsEven(n): return not n & 1").repeat(4, 10**6)
[0.18392395973205566, 0.18273091316223145, 0.1830739974975586, 0.18445897102355957]
<强> n % 2
强> ("== 0" and "not")
>>> timeit.Timer("modIsEven(1)", "def modIsEven(n): return n % 2 == 0").repeat(4, 10**6)
[0.22193098068237305, 0.22170782089233398, 0.21924591064453125, 0.21947598457336426]
>>> timeit.Timer("modIsEven(1)", "def modIsEven(n): return not n % 2").repeat(4, 10**6)
[0.20426011085510254, 0.2046220302581787, 0.2040550708770752, 0.2044820785522461]
重载运营商:
%
和&
运算符都已超载。
set
的bitwise和运算符重载。 s.intersection(t)
相当于s & t
,并返回一个&#34;新集,其中包含与s和t&#34;相同的元素。
>>> {1} & {1}
set([1])
这不会影响我们的条件:
>>> def bitwiseIsEven(n):
... return n & 1 == 0
>>> bitwiseIsEven('1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in bitwiseIsEven
TypeError: unsupported operand type(s) for &: 'str' and 'int'
>>> bitwiseIsEven({1})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in bitwiseIsEven
TypeError: unsupported operand type(s) for &: 'set' and 'int'
对于大多数非整数,模运算符也会抛出TypeError: unsupported operand type(s)
。
>>> def modIsEven(n):
... return n % 2 == 0
>>> modIsEven({1})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in modIsEven
TypeError: unsupported operand type(s) for %: 'set' and 'int'
它作为旧%-formatting
的字符串插值运算符重载。如果使用字符串进行比较,则会抛出TypeError: not all arguments converted during string formatting
。
>>> modIsEven('1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in modIsEven
TypeError: not all arguments converted during string formatting
如果字符串包含有效的转换说明符,则不会抛出。
>>> modIsEven('%d')
False
答案 1 :(得分:29)
此代码仅检查variable
的最低位是否为0.基于运算符优先级,这是:
if (variable & 1) == 0:
首先,将最低位与一位(仅提取最低位),然后检查它是否为0。
答案 2 :(得分:14)
&amp;是bitwise operator。它为两个操作数的每一位返回一个1位的整数,这两个操作数都是1,在所有其他位置都是0。例如:
a = 10 # 0b1010
b = 6 # 0b0110
a & b # 0b0010
现在,如果您有variable & 1
,则将variable
与0b1
进行比较,如果二进制表示中的最后一位数字为1,则仅返回1,否则为0。
答案 3 :(得分:6)
您唯一关心的可能是运营商&
。它是按位和,它采用两个操作数的二进制格式并执行&#34;逻辑和&#34;在每对比特上。
对于您的示例,请考虑以下事项:
variable = 2 #0b0010
if variable & 1 == 0:
print "condition satisfied" # satisfied, 0b0010 & 0b0001 = 0
variable = 5 #0b0101
if variable & 1 == 0:
print "condition satisfied" # not satisfied, 0b0101 & 0b0001 = 1
注意:强>
variable = 6 #0b0110
if variable & 2 == 0:
print "condition satisfied" # not satisfied, 0b0110 & 0b0010 = 2 (0b0010)