如何在Python中获得两个变量的逻辑异或?

例如,我有两个变量,我希望它们是字符串。我想测试它们中只有一个包含True值(不是None或空字符串):

str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")
if logical_xor(str1, str2):
    print "ok"
else:
    print "bad"

^操作符似乎是按位的,并不是在所有对象上都定义:

>>> 1 ^ 1
0
>>> 2 ^ 1
3
>>> "abc" ^ ""
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for ^: 'str' and 'str'

当前回答

只是因为我没有在其他地方看到过它,这也是一个诀窍:

def logical_xor(a, b):
    return not b if a else bool(b)

我不确定它是否比公认的解决方案bool(a) != bool(b)“更好”/更可读/更python化。

其他回答

我已经测试了几种方法(包括使用shadow wranger建议的truth()函数)。

%timeit  (not a) ^  (not b)   # 47 ns
%timeit  (not a) != (not b)   # 44.7 ns
%timeit truth(a) != truth(b)  # 116 ns
%timeit  bool(a) != bool(b)   # 190 ns

我们可以很容易地找到两个变量的xor:

def xor(a,b):
    return a !=b

例子:

xor(真,假)>>真

正如Zach解释的那样,你可以使用:

xor = bool(a) ^ bool(b)

就我个人而言,我喜欢一种略有不同的方言:

xor = bool(a) + bool(b) == 1

这种方言的灵感来自我在学校学习的一种逻辑图表语言,其中“OR”用一个包含≥1(大于或等于1)的方框表示,“XOR”用一个包含=1的方框表示。

这样做的优点是可以正确地实现独占或多个操作数。

"1 = a ^ b ^ c…"意思是真操作数的个数是奇数。这个运算符就是“奇偶校验”。 "1 = a + b + c…"意味着只有一个操作数为真。这是“排他的或”,意思是“一个排除其他的”。

你总是可以使用xor的定义从其他逻辑操作中计算它:

(a and not b) or (not a and b)

但这对我来说有点太啰嗦了,而且乍一看不是特别清楚。另一种方法是:

bool(a) ^ bool(b)

两个布尔值上的xor操作符是逻辑xor(不像整型值上的xor,它是按位的)。这是有意义的,因为bool只是int的一个子类,但被实现为只有值0和1。当域限制为0和1时,逻辑xor等价于按位xor。

所以logical_xor函数的实现方式如下:

def logical_xor(str1, str2):
    return bool(str1) ^ bool(str2)

感谢Python-3000邮件列表中的Nick Coghlan。

很多人,包括我自己,都需要一个类似于n输入异或电路的异或函数,其中n是变量。(见https://en.wikipedia.org/wiki/XOR_gate)。下面的简单函数实现了这一点。

def xor(*args):
   """
   This function accepts an arbitrary number of input arguments, returning True
   if and only if bool() evaluates to True for an odd number of the input arguments.
   """

   return bool(sum(map(bool,args)) % 2)

示例I/O如下:

In [1]: xor(False, True)
Out[1]: True

In [2]: xor(True, True)
Out[2]: False

In [3]: xor(True, True, True)
Out[3]: True