2015-04-16 4 views
24

fand ich dieses seltsame if -Anweisung in Code der jemand anderem:Seltsame if-Anweisung

if variable & 1 == 0: 

Ich verstehe es nicht. Es sollte zwei == haben, oder?

Kann jemand das erklären?

+4

Was wahrscheinlich ist verwirrend ist die &. Dies ist einer der bitweisen Operatoren von Python. Eine gute Post-Untersuchung, die man hier finden kann (http://stackoverflow.com/questions/1746613/bitwise-operation-and-usage). –

+0

Darf ich fragen, wo Sie das gefunden haben? Ich sehe in Python oft keine bitweisen Operatoren. – TigerhawkT3

+3

Es ist dasselbe wie 'variable% 2 == 0' für' int'egers. – Navith

Antwort

33

Die bedingte ist ein bitwise operator Vergleich:

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

Da viele der Kommentare sagen, für ganze Zahlen diese bedingte Wahr für Evens und Falsch für Odds ist. Der vorherrschende Weg, dies zu schreiben ist if variable % 2 == 0: oder if not variable % 2:

Mit timeit können wir sehen, dass es nicht viel Unterschied in der Leistung ist.

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] 

Überladene Operatoren:

Die Operatoren % und & sind überlastet.

Der bitweise Operator ist für set überlastet. s.intersection(t) entspricht s & t und gibt einen "neuen Satz mit gemeinsamen Elementen für s und t" zurück.

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

Dies wirkt sich nicht auf unsere bedingte:

>>> 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' 

Der Modulo-Operator auch TypeError: unsupported operand type(s) für die meisten Nicht-Ints werfen.

>>> 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' 

Es ist als Zeichenfolge Interpolationsoperator für die alte %-formatting überlastet. Es wird TypeError: not all arguments converted during string formatting ausgelöst, wenn eine Zeichenfolge für den Vergleich verwendet wird.

>>> 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 

Dies wird nicht ausgelöst, wenn die Zeichenfolge einen gültigen Konvertierungsspezifizierer enthält.

>>> modIsEven('%d') 
False 
+15

Es ist auch nützlich zu beachten, dass (für Integer) dieser Trick Ihnen sagen wird, ob die Zahl gerade ('True') oder ungerade (' False') ist. – baum

+1

@baum Sie sollten das eine Antwort machen - sieht aus wie Sie es bekommen haben (: BTW: afaik & ist nur für Ganzzahlen definiert (und Enten, die wie sie aussehen;) – drevicko

29

Dieser Code nur überprüft, ob das niedrigste Bit von variable ein 0 Basierend auf Operatorpräzedenz dies:

if (variable & 1) == 0: 

erste und das niedrigste Bit mit einem (Extrakt nur das niedrigste Bit), dann überprüfe, ob es 0 ist.

14

Die & ist eine bitwise operator. Er gibt eine Ganzzahl mit 1 Bit für jedes Bit seiner beiden Operanden zurück, die an allen anderen Stellen 1 und 0 sind. Zum Beispiel:

a = 10 # 0b1010 
b = 6 # 0b0110 
a & b # 0b0010 

Nun, wenn Sie variable & 1 haben, sind Sie variable gegen 0b1 vergleichen, die nur 1 zurück, wenn die letzte Ziffer in der binären Darstellung a 1 ist, sonst eine 0.

6

Ihre einzige Sorge ist wahrscheinlich der Betreiber &. Es ist ein bitweises und, das das binäre Format der zwei Operanden nimmt und "Logik und" auf jedem Paar Bits durchführt.

Für Ihr Beispiel ist Folgendes zu beachten:

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 

Hinweis:

variable = 6 #0b0110 
if variable & 2 == 0: 
    print "condition satisfied" # not satisfied, 0b0110 & 0b0010 = 2 (0b0010) 
+1

Es ist ein Tippfehler in Ihrer Antwort, in der ersten wenn Kommentar, du hast 0b0101 (5) statt 0b0010 (2) – ChristopheLec

+0

@ Majestic12 hinterlassen Danke, ich habe es editiert. –