Strange if statement

后端 未结 4 1435
甜味超标
甜味超标 2021-02-18 13:16

I found this strange if-statement in somebody else’s code:

if variable & 1 == 0:

I don\'t understand it. It should have two

4条回答
  •  粉色の甜心
    2021-02-18 14:00

    The conditional is a bitwise operator comparison:

    >>> 1 & 1
    1
    >>> 0 & 1
    0
    >>> a = 1
    >>> a & 1 == 0
    False
    >>> b = 0
    >>> b & 1 == 0
    True
    

    As many of the comments say, for integers this conditional is True for evens and False for odds. The prevalent way to write this is if variable % 2 == 0: or if not variable % 2:

    Using timeit we can see that there isn't much difference in performance.

    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]
    

    Overloaded Operators:

    Both the % and & operators are overloaded.

    The bitwise and operator is overloaded for set. s.intersection(t) is equivalent to s & t and returns a "new set with elements common to s and t".

    >>> {1} & {1}
    set([1])
    

    This doesn't effect our conditional:

    >>> def bitwiseIsEven(n):
    ...   return n & 1 == 0
    
    >>> bitwiseIsEven('1')
    Traceback (most recent call last):
      File "", line 1, in 
      File "", line 2, in bitwiseIsEven
    TypeError: unsupported operand type(s) for &: 'str' and 'int'
    >>> bitwiseIsEven({1})
    Traceback (most recent call last):
      File "", line 1, in 
      File "", line 2, in bitwiseIsEven
    TypeError: unsupported operand type(s) for &: 'set' and 'int'
    

    The modulo operator will also throw TypeError: unsupported operand type(s) for most non-ints.

    >>> def modIsEven(n):
    ...   return n % 2 == 0
    
    >>> modIsEven({1})
    Traceback (most recent call last):
      File "", line 1, in 
      File "", line 2, in modIsEven
    TypeError: unsupported operand type(s) for %: 'set' and 'int'
    

    It is overloaded as a string interpolation operator for the old %-formatting. It throws TypeError: not all arguments converted during string formatting if a string is used for the comparison.

    >>> modIsEven('1')
    Traceback (most recent call last):
      File "", line 1, in 
      File "", line 2, in modIsEven
    TypeError: not all arguments converted during string formatting
    

    This won't throw if the string includes a valid conversion specifier.

    >>> modIsEven('%d')
    False 
    

提交回复
热议问题