HOWTO · Python

Python の XOR(排他的論理和)

このチュートリアルでは、Python で整数とブール値に XOR 演算を適用する方法を説明します。^ 演算子、論理演算子、operator.xor() の使い方と実用例を紹介します。

このページの内容

XOR(排他的論理和)は、2つの値を比較し、ちょうど一方だけが真のときに真になる演算です。Python では、キャレット演算子(^)で整数とブール値の XOR を実行できます。どちらか一方だけを選びたい場合や、ビットを直接比較したい場合に使用します。

XOR とは?

XOR は2つのビットを比較し、値が異なるときに 1、同じときに 0 を返します。

  • 0 XOR 0 = 0
  • 0 XOR 1 = 1
  • 1 XOR 0 = 1
  • 1 XOR 1 = 0

ブール値にも同じ規則が適用され、True がちょうど1つだけなら True になります。整数では、Python がビットの各組み合わせにこの規則を個別に適用します。そのため、ブール値の XOR とビット単位の XOR は関連していますが、用途は異なります。

整数に XOR を使用する

キャレット演算子(^)を使用すると、2つの整数に対するビット単位の XOR を計算できます。

a = 5  # Binary: 0101
b = 3  # Binary: 0011

result = a ^ b
print(result)
6

5 の2進表現は 0101、3 の2進表現は 0011 です。対応するビットを比較すると、次のようになります。

  • 0 XOR 0 = 0
  • 1 XOR 0 = 1
  • 0 XOR 1 = 1
  • 1 XOR 1 = 0

結果は 0110 で、10進数では 6 です。先頭のゼロは2つのオペランドの桁をそろえるためだけのもので、値は変わりません。

ブール値に XOR を使用する

Python では、ブール値にも ^ を適用できます。次のプログラムは、4つの入力の組み合わせをすべて示すとともに、and、or、not で構成したブール値向けの実装も示します。

def xor(left, right):
    return (left and not right) or (not left and right)

for left, right in ((False, False), (False, True), (True, False), (True, True)):
    print(f"{left} ^ {right} -> {left ^ right}; xor() -> {xor(left, right)}")
False ^ False -> False; xor() -> False
False ^ True -> True; xor() -> True
True ^ False -> True; xor() -> True
True ^ True -> False; xor() -> False

この関数は、ブール値の式に名前付きの操作を持たせたい場合に便利です。ブール値を入力した場合、left ^ right と xor(left, right) は同じ4つの結果を返します。この論理形式はブール条件を対象としているため、整数のビット操作には ^ を使用してください。

XOR の実用的な使い方

operator モジュールには、xor() 関数と同じ演算を行う関数が用意されています。関数オブジェクトが必要な場合に便利で、ブール値と整数の両方のオペランドに使用できます。operator.xor() は ^ と同じ結果を返します。

from operator import xor

print(xor(True, False))
print(xor(5, 3))
True
6

よく知られたビット単位のテクニックとして、一時変数を使わずに2つの整数変数を入れ替える方法もあります。

x = 10
y = 20

x = x ^ y
y = x ^ y
x = x ^ y

print(x, y)
20 10

2つの整数から始めると、3つの演算は次のように動作します。

  1. x を x と y の XOR に更新します。
  2. 新しい x と y を XOR して、y を元の x の値に更新します。
  3. 同じ考え方で x を元の y の値に更新します。

この方法は整数変数では正しく動作しますが、通常の Python コードではタプルアンパッキングの x, y = y, x のほうが一般に明快です。XOR を使う方法は、主にビット単位の演算を理解したい場合や、XOR の使用が明示的に求められる制約がある場合に役立ちます。

まとめ

Python で XOR を使うには ^ を使用します。^ はブール値を直接比較し、オペランドが整数の場合は各ビットを比較します。operator.xor() 関数は同じ演算を関数形式で提供し、and、or、not を使えばブール値に対する規則を明示的に表現できます。論理演算かビット演算かに応じて、意味が最も伝わる形式を選んでください。

FAQ

  1. Python における XOR とは何ですか?
    XOR は排他的論理和です。2つの入力のうちちょうど一方だけが真の場合に真になります。整数のオペランドでは、この規則を対応する各ビットに適用します。

  2. Python で2つの整数に XOR 演算を行うにはどうすればよいですか?
    キャレット演算子を使用します。result = a ^ b のように記述してください。

  3. Python でブール値に XOR を使用できますか?
    はい。True ^ False と False ^ True は True になり、同じブール値どうしの入力は False になります。

  4. プログラミングにおける XOR の実用例は何ですか?
    3つのビット演算によって、2つの整数変数を入れ替える方法に XOR を使用できます。通常の Python コードでは、タプルアンパッキングのほうが一般に明快です。

  5. Python の XOR は可換ですか?
    はい。XOR は可換なので、互換性のあるオペランドでは a ^ b は b ^ a と等しくなります。