奇怪如果声明

n0t*_*tis 23 python if-statement python-2.7

if在其他人的代码中发现了这个奇怪的陈述:

if variable & 1 == 0:
Run Code Online (Sandbox Code Playgroud)

我不明白.应该有两个==吧?

有人可以解释一下吗?

DTi*_*ing 33

条件是按位运算符比较:

>>> 1 & 1
1
>>> 0 & 1
0
>>> a = 1
>>> a & 1 == 0
False
>>> b = 0
>>> b & 1 == 0
True
Run Code Online (Sandbox Code Playgroud)

正如许多评论所说,对于整数,这个条件对于平均而言是真的,对于赔率是假的.写这个的流行方式是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]
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

重载运算符:

无论是%&运营商都超载.

按位和运算符重载set.s.intersection(t)等效于s & t并返回"具有s和t共有元素的新集合".

>>> {1} & {1}
set([1])
Run Code Online (Sandbox Code Playgroud)

这不会影响我们的条件:

>>> 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'
Run Code Online (Sandbox Code Playgroud)

模数运算符也会抛出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'
Run Code Online (Sandbox Code Playgroud)

它被重载为旧的字符串插值运算符%-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
Run Code Online (Sandbox Code Playgroud)

如果字符串包含有效的转换说明符,则不会抛出此异常.

>>> modIsEven('%d')
False 
Run Code Online (Sandbox Code Playgroud)

  • 注意(对于整数),这个技巧会告诉你数字是偶数("真")还是奇数("假")也是有用的. (15认同)

小智 29

此代码仅检查最低位variable是否为0.基于运算符优先级,这是:

if (variable & 1) == 0:
Run Code Online (Sandbox Code Playgroud)

首先和最低位一(提取最低位),然后检查它是否为0.


Mas*_*din 14

&是一个按位运算符.它为两个操作数的每一位返回一个1位的整数,这两个操作数都是1,在所有其他位置都是0.例如:

a = 10 # 0b1010
b = 6  # 0b0110
a & b  # 0b0010
Run Code Online (Sandbox Code Playgroud)

现在,如果你有variable & 1,你是比较variable反对0b1这只会返回1,如果在二进制表示,去年的数字是1,否则为0.


Tho*_*ieh 6

您唯一关心的可能是运营商&.它是一个按位,它采用两个操作数的二进制格式,并在每对位上执行"逻辑和".

对于您的示例,请考虑以下事项:

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
Run Code Online (Sandbox Code Playgroud)

注意:

variable = 6  #0b0110
if variable & 2 == 0:
    print "condition satisfied" # not satisfied, 0b0110 & 0b0010 = 2 (0b0010)
Run Code Online (Sandbox Code Playgroud)