ตัวดำเนินการคาเร็ต (^) ใน Python ทำอะไร


111

วันนี้ฉันวิ่งข้ามตัวดำเนินการคาเร็ตใน python และลองใช้ฉันได้ผลลัพธ์ต่อไปนี้:

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

ดูเหมือนว่าจะขึ้นอยู่กับ 8 ดังนั้นฉันจึงคาดเดาการทำงานของไบต์บางประเภท? ดูเหมือนว่าฉันจะหาไซต์ที่ค้นหานี้ไม่ได้มากนักนอกจากจะมีพฤติกรรมแปลก ๆ สำหรับการลอยตัวแล้วใครมีลิงก์ไปยังสิ่งที่ตัวดำเนินการนี้ทำหรือคุณสามารถอธิบายได้ที่นี่


4
สำหรับจำนวนเต็มสิ่งเดียวกันใน C. ^ _-
Mike DeSimone

15
FYI จาก python shell คุณสามารถพิมพ์help('^')
seth

6
โปรดทราบว่ามันไม่ได้ทำงานผิดปกติสำหรับการลอยตัว (มันใช้ไม่ได้กับการลอย!) นอกจากนี้โปรดทราบว่าหลาย ๆ คนบังเอิญเจอสิ่งนี้ในขณะที่กำลังมองหา**ตัวดำเนินการเลขชี้กำลัง
Mike Graham

3
@seth: help('^')ไม่ทำอะไรเลยใน Python 2.6.1 ของฉัน (แอปเปิ้ลบิลด์) @ S.Lott: คุณหมายถึงสิ่งนี้ ( docs.python.org/reference/… ) เมื่อคุณพูดว่า "ครอบคลุมทั้งหมด" หรือไม่? ดูเหมือนจะเบาบางไปหน่อยสำหรับคนที่ไม่คุ้นเคยกับแนวคิดนี้ ...
ChristopheD

3
ขอบคุณทุกคนฉันเดาว่าถ้าฉันรู้ว่ามันเป็นตัวดำเนินการที่มีไหวพริบฉันจะรู้ว่าต้องดูที่ไหน แต่ฉันทำไม่ได้ดังนั้นคำถามนี้ :) ขอบคุณทุกคนสำหรับคำตอบของคุณพวกเขาแต่ละคนมีประโยชน์และตอนนี้ฉันรู้มากขึ้นเล็กน้อย ! :)
ทอด

คำตอบ:


173

มันเป็นXOR แบบบิต (เอกสิทธิ์เฉพาะหรือ)

ผลลัพธ์จะเป็นจริงถ้าหนึ่งตัวถูกดำเนินการ (และเพียงตัวเดียว) (ประเมินเป็น) จริง

เพื่อแสดงให้เห็น:

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

เพื่ออธิบายตัวอย่างของคุณเอง:

>>> 8^3
11

ลองคิดดูดังนี้:

1000 # 8 (ไบนารี)
0011 # 3 (ไบนารี)
---- # ใช้ XOR ('แนวตั้ง')
1011 # ผลลัพธ์ = 11 (ไบนารี)

14
ตัวอย่างเล็กน้อยตัวอย่างอื่น ๆ อาจรวมทั้งตัวเลขที่มีในบิตเดียวที่จะทำให้มันชัดเจนว่า1 1 xor 1 = 0
Mike Graham

1
ฉันต้องการเพิ่มคุณสามารถทำเลขฐานสองได้โดยพิมพ์โดย0bXที่ X คือเลขฐานสองของคุณ 0b0001, 0b0010ฯลฯ ดังนั้น0b1101 ^ 0b1110จะให้คุณ0b0011(หรือ 3)
Jeff

ฉันคิดว่า "ผลลัพธ์จะเป็นจริงถ้าตัวถูกดำเนินการหนึ่ง (และเพียงตัวเดียว) (ประเมินว่าเป็น) จริง" ไม่แน่นอนมันจะเป็นคำจำกัดความของ xor บูลีน
Xavier Combelle

42

มันเรียกใช้__xor__()หรือ__rxor__()เมธอดของอ็อบเจ็กต์ตามต้องการซึ่งสำหรับประเภทจำนวนเต็มจะใช้บิตเอกสิทธิ์หรือ.


4
+1 สำหรับการชี้ให้เห็นสิ่งที่มันจริงๆไม่นอกของการดำเนินงานจำนวนเต็ม
Mike DeSimone


8

โดยทั่วไปสัญลักษณ์^เป็นมัดรุ่นของ__xor__หรือ__rxor__วิธีการ ไม่ว่าประเภทข้อมูลใดก็ตามที่วางไว้ทางด้านขวาและด้านซ้ายของสัญลักษณ์จะต้องใช้ฟังก์ชันนี้ในลักษณะที่เข้ากันได้ สำหรับจำนวนเต็มเป็นการXORดำเนินการทั่วไปแต่ตัวอย่างเช่นไม่มีนิยามในตัวของฟังก์ชันสำหรับ type floatwith type 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'

สิ่งหนึ่งที่เรียบร้อยเกี่ยวกับ Python คือคุณสามารถแทนที่พฤติกรรมนี้ในคลาสของคุณเองได้ ตัวอย่างเช่นในบางภาษา^สัญลักษณ์หมายถึงการยกกำลัง คุณสามารถทำได้ด้วยวิธีนี้เช่นเดียวกับตัวอย่าง:

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

จากนั้นสิ่งนี้จะใช้งานได้และตอนนี้สำหรับอินสแตนซ์Fooเท่านั้นที่^สัญลักษณ์จะหมายถึงการยกกำลัง

In [16]: x = Foo(3)

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

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

ว้าวเป็นไปได้ไหม และเราอาจเปลี่ยนวิธี+การทำงานของตัวดำเนินการได้หรือไม่
K DawG

ใช่นี่คือวิธีที่+สัญลักษณ์สามารถดำเนินการแบบหนึ่งสำหรับlist(การเรียงต่อกัน) ในขณะที่ดำเนินการประเภทอื่น (การบวกทางคณิตศาสตร์) สำหรับประเภทตัวเลข ในกรณีนี้คุณจะแทนที่__add__or __radd__method ในชั้นเรียนของคุณ
ely

1
ตามหมายเหตุด้านข้าง__r*__เวอร์ชันของสิ่งเหล่านี้ (เหมือน__rxor__หรือ__radd__) จะถูกเรียกใช้จากอาร์กิวเมนต์ที่ปรากฏทางด้านขวามือของสัญลักษณ์ infix และเฉพาะในกรณีที่การเรียกใช้ฟังก์ชันสำหรับสัญลักษณ์ทางซ้ายไม่ทำงาน คุณสามารถคิดได้try: left_hand_symbol.__xor__(right_hand_symbol); except: right_hand_symbol.__rxor__(left_hand_symbol)แต่xorสามารถแทนที่ได้ด้วยตัวดำเนินการ infix ที่มีอยู่ในไฟล์หลามรูปแบบข้อมูล
ely

นั่นหมายความว่าฉันสามารถสร้างตัวดำเนินการของตัวเองซึ่งอนุญาตให้intเชื่อมต่อกับสตริงได้หรือไม่? มนุษย์งูหลามซับซ้อนกว่าที่คิด
K DawG

1
คุณสามารถพูดทำนอง(CompositionA | CompositionB) // CompositionCว่า "เล่นองค์ประกอบ A ตามด้วยองค์ประกอบ B ในขณะเดียวกันก็เล่นองค์ประกอบ C ไปพร้อม ๆ กันด้วย" พูดคุยเกี่ยวกับโค้ดที่สวยงาม!
ely

3

เมื่อคุณใช้^โอเปอเรเตอร์__xor__จะเรียกวิธีการด้านหลังม่าน

a^bเทียบเท่ากับa.__xor__(b).

นอกจากนี้ยังa ^= bเทียบเท่ากับa = a.__ixor__(b)(ซึ่ง__xor__ใช้เป็นทางเลือกเมื่อ__ixor__ถูกเรียกโดยปริยายผ่านการใช้^=แต่ไม่มีอยู่)

โดยหลักการแล้วสิ่งที่__xor__ทำขึ้นอยู่กับการนำไปใช้อย่างสมบูรณ์ กรณีการใช้งานทั่วไปใน Python ได้แก่ :

  • ความแตกต่างแบบสมมาตรของเซต (องค์ประกอบทั้งหมดอยู่ในหนึ่งในสองชุด)

การสาธิต:

>>> a = {1, 2, 3}
>>> b = {1, 4, 5}
>>> a^b
{2, 3, 4, 5}
>>> a.symmetric_difference(b)
{2, 3, 4, 5}
  • Bitwise Non-Equalสำหรับบิตของจำนวนเต็มสองจำนวน

การสาธิต:

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

คำอธิบาย:

    101 (5 decimal)
XOR 110 (6 decimal)
-------------------
    011 (3 decimal)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.