Python'daki düzeltme operatörü (^) ne yapar?


111

Bugün python'da düzeltme operatörü ile karşılaştım ve denedim, aşağıdaki çıktıyı aldım:

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

Görünüşe göre 8'e dayanıyor, yani bir çeşit bayt işlemi mi tahmin ediyorum? Bu arama siteleri hakkında, şamandıralar için tuhaf davranması dışında pek bir şey bulamıyorum, bu operatörün ne yaptığına bir bağlantısı olan var mı veya burada açıklayabilir misiniz?


4
Tamsayılar için, C'de yaptığı aynı şey. ^ _-
Mike DeSimone

15
Bilginize, python kabuğundan yazabilirsinizhelp('^')
seth

6
Şamandıralar için tuhaf davranmadığını unutmayın (sadece şamandıralarla çalışmaz!). Ayrıca, birçok kişinin **üs alma operatörünü ararken yanlışlıkla buna rastladığını unutmayın .
Mike Graham

3
@seth: help('^')Python 2.6.1 (elma yapısı) içinde hiçbir şey yapmaz. @ S.Lott: "tamamen kapsanmış" derken bunu mu kastediyorsunuz ( docs.python.org/reference/… ) ?. Konsepte aşina olmayan biri için biraz seyrek görünüyor ...
ChristopheD

3
Hepinize teşekkürler, sanırım bunun bitsel bir operatör olduğunu bilseydim, tam olarak nereye bakacağımı bilirdim, ama bilmiyordum, dolayısıyla soru :) Hepinize cevaplarınız için teşekkürler, her biri yardımcı oldu ve şimdi biraz daha fazlasını biliyorum ! :)
Fry

Yanıtlar:


173

Bitsel ÖZELVEYA'dır (özel VEYA).

İşlenenlerden biri (ve yalnızca biri) (doğru olarak değerlendirilirse) true olur.

Göstermek:

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

Kendi örneklerinizden birini açıklamak için:

>>> 8^3
11

Bunu şu şekilde düşünün:

1000 # 8 (ikili)
0011 # 3 (ikili)
---- # ÖZELVEYA UYGULA ('dikey olarak')
1011 # sonuç = 11 (ikili)

14
Biraz daha açıklayıcı bir örnek 1, bunu açıklığa kavuşturmak için her iki sayının da aynı bitte olmasını içerebilir 1 xor 1 = 0.
Mike Graham

1
Eklemek istedim, 0bXX'in ikiliniz olduğu yeri yazarak ikili sayılar yapabilirsiniz . 0b0001, 0b0010vb. Yani, 0b1101 ^ 0b1110size 0b0011(veya 3) verir.
Jeff

Bence "İşlenenlerden biri (ve yalnızca biri) (olarak değerlendirilir) doğru olursa doğru olur." kesin değil, bir boolean
xor'un

42

Gerektiğinde nesnenin __xor__()veya __rxor__()yöntemini çağırır, tamsayı türleri için bit düzeyinde özel-veya.


4
+1 , tamsayı işleminin dışında gerçekten ne yaptığını işaret etmek için .
Mike DeSimone


8

Genel olarak, sembol veya yöntemlerinin ^bir infix versiyonudur . Sembolün sağına ve soluna yerleştirilen veri türleri ne olursa olsun, bu işlevi uyumlu bir şekilde uygulamalıdır. Tamsayılar için, bu genel işlemdir, ancak örneğin tür ile tür için işlevin yerleşik bir tanımı yoktur :__xor____rxor__XORfloatint

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 ile ilgili güzel bir şey, bu davranışı kendi sınıfınızda geçersiz kılabilmenizdir. Örneğin, bazı dillerde ^sembol üs alma anlamına gelir. Bunu bir örnek olarak şu şekilde yapabilirsiniz:

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

O zaman böyle bir şey işe yarayacak ve şimdi sadece örnekler Fooiçin , ^sembol üs alma anlamına gelecektir.

In [16]: x = Foo(3)

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

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

woah, bu mümkün mü? ve muhtemelen +operatörün çalışma şeklini de değiştirebilir miyiz ?
K DawG

Evet, +sembol, listsayısal türler için başka tür bir eylem (matematiksel toplama) yaparken (birleştirme) için bir tür eylemi bu şekilde yapabilir . Bu durumda, sınıfınızdaki __add__veya __radd__yöntemlerini geçersiz kılarsınız.
ely

1
Bir yan not olarak, bunların __r*__versiyonu (gibi __rxor__veya __radd__) , infix sembolünün sağ tarafında görünen argümandan çağrılacaktır ve sadece sol el sembolü için fonksiyon çağrısı çalışmazsa. Bunu şöyle düşünebilirsiniz try: left_hand_symbol.__xor__(right_hand_symbol); except: right_hand_symbol.__rxor__(left_hand_symbol), ancak Python Veri Modelindekixor mevcut infix operatörlerinden herhangi biri ile değiştirilebilir .
ely

Yani bu int, dizelerle birleştirmeye izin veren kendi operatörümü oluşturabileceğim anlamına mı geliyor? dostum, python düşündüğümden çok karmaşık
K DawG

1
Yani şöyle bir şey söyleyebilirsiniz (CompositionA | CompositionB) // CompositionCve bu sadece "Kompozisyon A'yı ve ardından B kompozisyonunu çalın, bu arada aynı zamanda C kompozisyonunu da paralel olarak çalın" anlamına gelir. Güzel bir kod parçası hakkında konuşun!
ely

3

^Operatörü kullandığınızda perde arkasında yöntem __xor__denir.

a^beşdeğerdir a.__xor__(b).

Ayrıca, a ^= beşdeğerdir a = a.__ixor__(b)(burada örtük olarak using yoluyla çağrıldığında __xor__bir geri dönüş olarak __ixor__kullanılır, ^=ancak mevcut değildir).

Prensip olarak, ne __xor__olacağı tamamen uygulanmasına bağlıdır. Python'da yaygın kullanım durumları şunlardır:

  • Kümelerin Simetrik Farkı (tüm elemanlar tam olarak iki kümeden birinde bulunur)

Demo:

>>> a = {1, 2, 3}
>>> b = {1, 4, 5}
>>> a^b
{2, 3, 4, 5}
>>> a.symmetric_difference(b)
{2, 3, 4, 5}
  • İki tamsayının bitleri için Bitsel Eşit Olmayan

Demo:

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

Açıklama:

    101 (5 decimal)
XOR 110 (6 decimal)
-------------------
    011 (3 decimal)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.