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

当前回答

这就是我编写真值表的方法。对于xor,我们有:

| a | b  | xor   |             |
|---|----|-------|-------------|
| T | T  | F     |             |
| T | F  | T     | a and not b |
| F | T  | T     | not a and b |
| F | F  | F     |             |

看看答案列中的T值,用逻辑上的或将所有真情况串在一起。所以,这个真值表可以在情况2或3中产生。因此,

xor = lambda a, b: (a and not b) or (not a and b)

其他回答

Xor在Python中是^。它返回:

int型的逐位xor bool的逻辑xor 集合的独占联合 实现__xor__的类的用户定义结果。 TypeError用于未定义的类型,例如字符串或字典。

如果你打算在字符串上使用它们,将它们转换为bool类型可以使你的操作明确(也可以是set(str1) ^ set(str2))。

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

假设A和B是bool。

A is not B

这是映射-缩减泛化的实现。注意,这相当于functools。Reduce (lambda x, y: x != y, map(bool, orands))。

def xor(*orands):
    return bool(sum(bool(x) for x in orands) % 2)

如果你在寻找一个单一热点探测器,这是一个概括。这种概括可能适用于英语中exclusive-or的用法(例如:“花一美元,你可以买一杯果汁、咖啡或茶”),但这与典型的操作顺序不符。E.g.xor_1hot (1 1 1) = = 0 ! = 1 = = xor_1hot (xor_1hot(1, 1), 1)。

def xor_1hot(*orands):
    return sum(bool(x) for x in orands) == 1

你可以用

# test
from itertools import product
n = 3
total_true = 0
for inputs in product((False, True), repeat=n):
    y = xor(*inputs)
    total_true += int(y)
    print(f"{''.join(str(int(b)) for b in inputs)}|{y}")
print('Total True:', total_true)

单热检测器输出:

000 |假 001 |真 010 |真 011 |假 100 |真 101 |假 110 |假 111 |假 总数正确:3

使用映射-规约模式输出:

000 |假 001 |真 010 |真 011 |假 100 |真 101 |假 110 |假 111 |真 总数:4

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

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

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