如何在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'

当前回答

有时我发现自己使用1和0而不是布尔值True和False。在这种情况下,xor可以定义为

z = (x + y) % 2

它有如下的真值表:

     x
   |0|1|
  -+-+-+
  0|0|1|
y -+-+-+
  1|1|0|
  -+-+-+

其他回答

Python处理逻辑操作的方式可能令人困惑,因此我的实现为用户提供了一个简单的True/False答案选项(默认情况下)。实际的Python结果可以通过将可选的第三个参数设置为None来获得。

def xor(a, b, true=True, false=False): # set true to None to get actual Python result
    ab1 = a and not b
    ab2 = not a and b
    if bool(ab1) != bool(ab2):
        return (ab1 or ab2) if true is None else true
    else:
        return false

这将获得两个(或多个)变量的逻辑独占异或

str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")

any([str1, str2]) and not all([str1, str2])

这种设置的第一个问题是,它很可能遍历整个列表两次,并且至少会检查至少一个元素两次。因此,它可以提高代码的理解能力,但不能提高速度(根据您的用例,速度可能略有不同)。

这种设置的第二个问题是,无论变量的数量如何,它都会检查排他性。这可能一开始被认为是一个特征,但随着变量数量的增加,第一个问题变得更加重要(如果它们确实如此的话)。

我知道说这个有点晚了,但我有个想法也许值得,只是作为文档。也许这样可以:np.abs(x-y

如果x=True=1和y=False=0,那么结果将是|1-0|=1=True 如果x=False=0和y=False=0,那么结果将是|0-0|=0=False 如果x=True=1和y=True=1,那么结果将是|1-1|=0=False 如果x=False=0和y=True=1,那么结果将是|0-1|=1=True

正如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…"意味着只有一个操作数为真。这是“排他的或”,意思是“一个排除其他的”。

Python逻辑或:A或B:如果bool(A)为True则返回A,否则返回B Python逻辑和:A和B:如果bool(A)为False则返回A,否则返回B

为了保持这种思维方式,我的逻辑xor定义将是:

def logical_xor(a, b):
    if bool(a) == bool(b):
        return False
    else:
        return a or b

这样它就可以返回a, b或False:

>>> logical_xor('this', 'that')
False
>>> logical_xor('', '')
False
>>> logical_xor('this', '')
'this'
>>> logical_xor('', 'that')
'that'