2015-04-16 13 views
24

tôi thấy lạ if -statement này trong mã của người khác:Strange lệnh if

if variable & 1 == 0: 

Tôi không hiểu nó. Nó phải có hai ==, phải không?

Ai đó có thể giải thích điều này?

+4

gì có lẽ là khó hiểu là &. Đây là một trong những toán tử bitwise của Python. Một bài kiểm tra tốt có thể được tìm thấy [ở đây] (http://stackoverflow.com/questions/1746613/bitwise-operation-and-usage). –

+0

Tôi có thể hỏi bạn đã tìm thấy ở đâu không? Tôi không thường thấy các toán tử bitwise trong Python. – TigerhawkT3

+3

Nó giống như 'biến% 2 == 0' cho' int'egers. – Navith

Trả lời

33

Câu điều kiện là một so sánh bitwise operator:

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

Như nhiều ý kiến ​​nói rằng, đối với số nguyên có điều kiện này là True cho làm mềm mại và False cho tỷ lệ cược. Cách phổ biến để viết điều này là if variable % 2 == 0: hoặc if not variable % 2:

Sử dụng timeit chúng ta có thể thấy rằng không có nhiều khác biệt về hiệu suất.

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] 

nhà khai thác quá tải:

Cả hai nhà khai thác %& đều bị quá tải.

Bitwise và toán tử bị quá tải cho set. s.intersection(t) tương đương với s & t và trả về "tập hợp mới có các phần tử phổ biến cho s và t".

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

này không ảnh hưởng đến điều kiện của chúng tôi:

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

Nhà điều hành modulo cũng sẽ ném TypeError: unsupported operand type(s) cho hầu hết các phi ints.

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

Nó bị quá tải như toán tử nội suy chuỗi cho số %-formatting cũ. Nó ném TypeError: not all arguments converted during string formatting nếu một chuỗi được sử dụng để so sánh.

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

Điều này sẽ không xảy ra nếu chuỗi bao gồm trình chỉ định chuyển đổi hợp lệ.

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

Nó cũng hữu ích để lưu ý rằng (cho số nguyên), thủ thuật này sẽ cho bạn biết nếu số thậm chí là ('True') hoặc lẻ (' Sai'). – baum

+1

@baum bạn nên làm cho rằng một câu trả lời - có vẻ như bạn đã nhận nó (: btw: afaik & chỉ được xác định cho số nguyên (và vịt trông giống chúng;) – drevicko

29

Mã này chỉ kiểm tra nếu các bit thấp nhất của variable là 0. Dựa trên ưu tiên toán tử này là:

if (variable & 1) == 0: 

đầu tiên và bit thấp nhất với một (chiết xuất chỉ bit thấp nhất), sau đó kiểm tra nếu nó là 0.

14

& là bitwise operator. Nó trả về một số nguyên với 1 bit cho mỗi bit của hai toán hạng của nó là cả 1 và 0 ở tất cả các vị trí khác. Ví dụ:

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

Bây giờ, nếu bạn có variable & 1, bạn đang so sánh variable chống 0b1 mà sẽ chỉ trả lại 1 nếu đó là chữ số cuối cùng trong biểu diễn nhị phân là 1, nếu không một 0.

6

của bạn mối quan tâm duy nhất có lẽ là toán tử &. Đó là bitwise và có định dạng nhị phân của hai toán hạng và thực hiện "logic và" trên mỗi cặp bit.

Ví dụ, hãy xem xét những điều sau đây:

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 

Lưu ý:

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

Có lỗi đánh máy trong câu trả lời của bạn, trong phần đầu tiên nếu nhận xét, bạn đã để lại 0b0101 (5) thay vì 0b0010 (2) – ChristopheLec

+0

@ Majestic12 Cảm ơn bạn! Tôi đã chỉnh sửa. –