Toán tử dấu mũ (^) trong Python làm gì?


111

Tôi đã chạy qua toán tử dấu mũ trong python hôm nay và thử nó, tôi nhận được kết quả sau:

>>> 8^3
11
>>> 8^4
12
>>> 8^1
9
>>> 8^0
8
>>> 7^1
6
>>> 7^2
5
>>> 7^7
0
>>> 7^8
15
>>> 9^1
8
>>> 16^1
17
>>> 15^1
14
>>>

Nó dường như dựa trên 8, vì vậy tôi đoán một số loại hoạt động byte? Tôi dường như không thể tìm thấy nhiều điều về các trang web tìm kiếm này ngoài việc nó hoạt động kỳ lạ với float, có ai có liên kết đến nhà điều hành này làm gì không hoặc bạn có thể giải thích nó ở đây không?


4
Đối với số nguyên, điều tương tự nó trong C. ^ _-
Mike Desimone

15
FYI, từ vỏ python, bạn có thể gõhelp('^')
Seth

5
Lưu ý rằng nó không hoạt động kỳ lạ đối với float (nó chỉ không hoạt động với float!). Cũng lưu ý rằng nhiều người vô tình gặp phải điều này trong khi tìm kiếm **, toán tử lũy thừa.
Mike Graham

3
@seth: help('^')không làm gì trong Python 2.6.1 (bản dựng apple) của tôi. @ S.Lott: ý của bạn là ( docs.python.org/reference/… ) khi bạn đang nói "hoàn toàn được che đậy" ?. Có vẻ thưa thớt bit cho một người nào đó không quen thuộc với khái niệm ...
ChristopheD

3
Cảm ơn tất cả, tôi đoán nếu tôi biết đó là một toán tử thông minh, tôi sẽ biết ngay nơi để tìm, nhưng tôi đã không, do đó câu hỏi :) Cảm ơn tất cả các câu trả lời của bạn, mỗi câu trả lời đều hữu ích và bây giờ tôi biết thêm một chút ! :)
Fry

Câu trả lời:


173

Đó là một XOR bitwise (HOẶC độc quyền).

Kết quả là true nếu một (và chỉ một) trong các toán hạng (đánh giá là) true.

Để lam sang tỏ:

>>> 0^0
0
>>> 1^1
0
>>> 1^0
1
>>> 0^1
1

Để giải thích một trong những ví dụ của riêng bạn:

>>> 8^3
11

Nghĩ về nó theo cách này:

1000 # 8 (nhị phân)
0011 # 3 (nhị phân)
---- # ÁP DỤNG XOR ('theo chiều dọc')
1011 # kết quả = 11 (nhị phân)

14
Một ví dụ minh họa hơn một chút có thể bao gồm cả hai số có 1cùng một bit để làm rõ điều đó 1 xor 1 = 0.
Mike Graham

1
Tôi muốn nói thêm, bạn có thể tính số nhị phân bằng cách nhập 0bXX là số nhị phân của bạn. 0b0001, 0b0010v.v. Vì vậy, 0b1101 ^ 0b1110sẽ cung cấp cho bạn 0b0011(hoặc 3).
Jeff,

Tôi nghĩ "Kết quả là true nếu một (và chỉ một) trong các toán hạng (đánh giá) true." không phải là chính xác, nó sẽ là gì định nghĩa của một xor boolean
Xavier Combelle

42

Nó gọi phương thức __xor__()hoặc __rxor__()của đối tượng khi cần thiết, đối với kiểu số nguyên thực hiện một bitwise độc ​​quyền-hoặc.


4
+1 để chỉ ra những gì nó thực sự hoạt động, bên ngoài hoạt động số nguyên.
Mike DeSimone


8

Nói chung, biểu tượng ^là một ghi vào phiên bản của __xor__hoặc __rxor__phương pháp. Bất kỳ kiểu dữ liệu nào được đặt ở bên phải và bên trái của biểu tượng phải thực hiện chức năng này theo cách tương thích. Đối với số nguyên, đây là phép toán phổ biến XOR, nhưng ví dụ: không có định nghĩa tích hợp sẵn của hàm cho kiểu floatcó kiểu int:

In [12]: 3 ^ 4
Out[12]: 7

In [13]: 3.3 ^ 4
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-13-858cc886783d> in <module>()
----> 1 3.3 ^ 4

TypeError: unsupported operand type(s) for ^: 'float' and 'int'

Một điều thú vị về Python là bạn có thể ghi đè hành vi này trong một lớp của riêng bạn. Ví dụ, trong một số ngôn ngữ, ^biểu tượng có nghĩa là lũy thừa. Bạn có thể làm điều đó theo cách này, chỉ như một ví dụ:

class Foo(float):
    def __xor__(self, other):
        return self ** other

Sau đó, một cái gì đó như thế này sẽ hoạt động, và bây giờ, đối với các trường hợp Foochỉ , ^ký hiệu sẽ có nghĩa là lũy thừa.

In [16]: x = Foo(3)

In [17]: x
Out[17]: 3.0

In [18]: x ^ 4
Out[18]: 81.0

woah, điều đó thậm chí có thể? và chúng ta có thể thay đổi cách +hoạt động của toán tử không?
K DawG

Có, đây là cách +biểu tượng có thể thực hiện một loại hành động cho list(nối) trong khi thực hiện một loại hành động khác (phép cộng toán học) cho các kiểu số. Trong trường hợp đó, bạn sẽ ghi đè __add__hoặc __radd__các phương thức trong lớp của mình.
ely

1
Lưu ý thêm, __r*__phiên bản của chúng (như __rxor__hoặc __radd__) sẽ được gọi từ đối số xuất hiện ở phía bên phải của ký hiệu infix và chỉ khi lệnh gọi hàm cho ký hiệu bên trái không hoạt động. Bạn có thể nghĩ về nó như thế try: left_hand_symbol.__xor__(right_hand_symbol); except: right_hand_symbol.__rxor__(left_hand_symbol), nhưng xorcó thể được thay thế bằng bất kỳ toán tử infix nào có sẵn trong Mô hình dữ liệu Python .
ely

Vì vậy, điều đó có nghĩa là tôi có thể tạo toán tử của riêng mình cho phép intnối với chuỗi? người đàn ông, trăn là cách phức tạp hơn tôi nghĩ
K Dawg

1
Vì vậy, bạn có thể nói điều gì đó như (CompositionA | CompositionB) // CompositionCvà nó sẽ chỉ có nghĩa là "Chơi sáng tác A theo sau là sáng tác B, đồng thời phát sáng tác C song song cùng lúc." Nói về một đoạn mã đẹp!
ely

3

Khi bạn sử dụng ^toán tử, đằng sau bức màn, phương thức __xor__được gọi.

a^btương đương với a.__xor__(b).

Ngoài ra, a ^= btương đương với a = a.__ixor__(b)(where __xor__được sử dụng làm dự phòng khi __ixor__được gọi ngầm thông qua using ^=nhưng không tồn tại).

Về nguyên tắc, những gì __xor__làm là hoàn toàn phụ thuộc vào việc thực hiện nó. Các trường hợp sử dụng phổ biến trong Python là:

  • Sự khác biệt đối xứng của các tập hợp (tất cả các phần tử có trong chính xác một trong hai tập hợp)

Bản giới thiệu:

>>> a = {1, 2, 3}
>>> b = {1, 4, 5}
>>> a^b
{2, 3, 4, 5}
>>> a.symmetric_difference(b)
{2, 3, 4, 5}
  • Bitwise không bằng nhau cho các bit của hai số nguyên

Bản giới thiệu:

>>> a = 5
>>> b = 6
>>> a^b
3

Giải trình:

    101 (5 decimal)
XOR 110 (6 decimal)
-------------------
    011 (3 decimal)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.