如何在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化。

其他回答

你使用和C中一样的异或运算符,也就是^。

我不知道为什么,但投票最多的解决方案是bool(A) != bool(B),而我想说的是-与C的^运算符一致,最明显的解决方案是:

bool(A) ^ bool(B)

对于任何来自C或任何C衍生语言的人来说,它更易于阅读和立即理解……

在进行代码高尔夫时,可能是这样

not A ^ (not B)

将是赢家。使用not作为布尔值的转换器(比bool()小一个字母)。对于第一个表达式在某些情况下可以省略副命题。好吧,这要看情况,在必须不(A) ^ (not(B))的情况下,bool()需要相同数量的字母……

Exclusive Or的定义如下

def xor( a, b ):
    return (a or b) and not (a and b)

假设A和B是bool。

A is not B

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

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

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

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

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

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'