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
参考までに、Pythonシェルから次のように入力できますhelp('^')
セス

5
フロートでは奇妙な動作をしないことに注意してください(フロートでは動作しません!)。また**、指数演算子のを探しているときに、多くの人が誤ってこれに遭遇することにも注意してください。
マイクグラハム

3
@seth:help('^')私のPython 2.6.1(apple build)では何もしません。@ S.Lott:「完全にカバーされている」と言っているとき、これ(docs.python.org/reference/…)を意味しますか?コンセプトに不慣れな人には少しまばらに見えます...
ChristopheD

3
おかげで、ビットワイズ演算子だとわかっていれば、どこを見ればよいかわかっていたと思いますが、知りませんでした。したがって、質問:)すべての回答に感謝します。それぞれが役に立ちました。 !:)
Fry

回答:


173

これはビット単位のXOR(排他的OR)です。

オペランドの1 (および1つのみ)が真(評価)の場合、結果は真になります。

実証するには:

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

独自の例の1つを説明するには:

>>> 8^3
11

次のように考えてください。

1000#8(バイナリ)
0011#3(バイナリ)
----#APPLY XOR( 'vertically')
1011#結果= 11(バイナリ)

14
もう少し例は有する両方の数字が挙げられるかもしれない1、それはそれをクリアするために同じビットにします1 xor 1 = 0
マイクグラハム

1
追加したかったのですが0bX、Xが2進数であると入力すると、2進数を実行できます。0b00010b0010など。したがって、0b1101 ^ 0b1110あなた0b0011(または3)を与えるでしょう。
ジェフ

「オペランドの1つ(そして1つだけ)が真(評価)であれば、真になります」と私は思います。正確ではありません、それはブールxorの定義になります
Xavier Combelle



8

一般的に言えば、シンボル^はor メソッドのinfixバージョンです。シンボルの右側と左側に配置されるデータ型は、互換性のある方法でこの関数を実装する必要があります。整数の場合、これは一般的な操作ですが、たとえば、type がtypeの関数の組み込み定義はありません。__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の優れた点の1つは、独自のクラスでこの動作をオーバーライドできることです。たとえば、一部の言語では、^記号はべき乗を意味します。これは、1つの例と同じように行うことができます。

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

はい、これは、+シンボルがlist数値型に対して別の種類のアクション(数学的加算)を実行しながら(連結)に対して1種類のアクションを実行できる方法です。その場合は、クラスの__add__または__radd__メソッドをオーバーライドします。
2013年

1
ちなみに、__r*__これらのバージョン(__rxor__または__radd__)は、中置記号の右側に表示される引数から呼び出され、左側の記号の関数の呼び出しが機能しない場合にのみ呼び出されます。あなたはそれのようtry: left_hand_symbol.__xor__(right_hand_symbol); except: right_hand_symbol.__rxor__(left_hand_symbol)に考えることができますがxorPythonデータモデルで使用可能な任意の中置演算子で置き換えることができます。
2013年

つまり、int文字列との連結を可能にする独自の演算子を作成できるということです。 男、Pythonは思ったよりも複雑です
K DawG

1
たとえば(CompositionA | CompositionB) // CompositionC、「コンポジションAを再生してからコンポジションBを再生し、同時にコンポジションCを同時に再生する」という意味になります。美しいコードについて話してください!
2013年

3

^オペレーターを使用すると、カーテンの後ろでメソッド__xor__が呼び出されます。

a^bと同等a.__xor__(b)です。

また、a ^= bと同等ですa = a.__ixor__(b)(where __xor__は、__ixor__usingを介して暗黙的に呼び出され^=たが存在しない場合のフォールバックとして使用されます)。

原則として、何をするか__xor__は完全にその実装次第です。Pythonの一般的な使用例は次のとおりです。

  • セットの対称差(すべての要素が2つのセットのいずれかに正確に存在する)

デモ:

>>> a = {1, 2, 3}
>>> b = {1, 4, 5}
>>> a^b
{2, 3, 4, 5}
>>> a.symmetric_difference(b)
{2, 3, 4, 5}
  • 2つの整数のビットのビットごとの不等

デモ:

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