Ho trovato questo strano if
-affermazione nel codice di qualcun altro:Strano if
if variable & 1 == 0:
io non lo capisco. Dovrebbe avere due ==
, giusto?
Qualcuno può spiegarlo?
Ho trovato questo strano if
-affermazione nel codice di qualcun altro:Strano if
if variable & 1 == 0:
io non lo capisco. Dovrebbe avere due ==
, giusto?
Qualcuno può spiegarlo?
Il condizionale è un confronto bitwise operator:
>>> 1 & 1
1
>>> 0 & 1
0
>>> a = 1
>>> a & 1 == 0
False
>>> b = 0
>>> b & 1 == 0
True
Come molti dei commenti dicono, per gli interi questo condizionale è vero per livella e False per probabilità. Il modo più diffuso di scrivere questo è if variable % 2 == 0:
o if not variable % 2:
Usando timeit
possiamo vedere che non c'è molta differenza in termini di prestazioni.
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]
Operatori di overload:
Entrambi gli operatori %
e &
sono sovraccarichi.
Il bit per bit e l'operatore sono sovraccarichi per set
. s.intersection(t)
equivale a s & t
e restituisce un "nuovo set con elementi comuni a se t".
>>> {1} & {1}
set([1])
Questo non influenza il nostro condizionale:
>>> 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'
L'operatore modulo sarà anche buttare TypeError: unsupported operand type(s)
per la maggior parte dei non-int.
>>> 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'
di sovraccarico come operatore di interpolazione di stringhe per il vecchio %-formatting
. Getta TypeError: not all arguments converted during string formatting
se una stringa viene utilizzata per il confronto.
>>> 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
Questo non verrà generato se la stringa include un identificatore di conversione valido.
>>> modIsEven('%d')
False
Questo codice solo controlla se il bit più basso di variable
è uno 0. Sulla base di precedenza degli operatori questo è:
if (variable & 1) == 0:
primo e il bit più basso con uno (estratto solo il bit più basso), quindi controlla se è 0.
Il & è un bitwise operator. Restituisce un intero con 1 bit per ogni bit dei suoi due operandi che sono entrambi 1 e 0 in tutti gli altri luoghi. Per esempio:
a = 10 # 0b1010
b = 6 # 0b0110
a & b # 0b0010
Ora, se avete variable & 1
, si sta confrontando variable
contro 0b1
che restituirà solamente 1, se tale ultima cifra nella rappresentazione binaria è un 1, altrimenti 0.
tuo l'unica preoccupazione è probabilmente l'operatore &
. È un bit a bit e che accetta il formato binario dei due operandi ed esegue "logica e" su ogni coppia di bit.
Per esempio, si consideri il seguente:
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
Nota:
variable = 6 #0b0110
if variable & 2 == 0:
print "condition satisfied" # not satisfied, 0b0110 & 0b0010 = 2 (0b0010)
C'è un errore di battitura nella tua risposta, nel primo se commento, hai lasciato 0b0101 (5) invece di 0b0010 (2) – ChristopheLec
@ Majestic12 Grazie! Ho modificato. –
quello che probabilmente è fonte di confusione è il &. Questo è uno degli operatori bit a bit di Python. Un buon post che può essere esaminato [qui] (http://stackoverflow.com/questions/1746613/bitwise-operation-and-usage). –
Posso chiederti dove l'hai trovato? Non vedo spesso operatori bit a bit in Python. – TigerhawkT3
È uguale a 'variable% 2 == 0' per' int'egers. – Navith