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?
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?
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 %
và &
đề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
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.
& 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.
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)
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
@ Majestic12 Cảm ơn bạn! Tôi đã chỉnh sửa. –
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). –
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
Nó giống như 'biến% 2 == 0' cho' int'egers. – Navith