如何在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'
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'
在Python中获取两个或多个变量的逻辑异或:
将输入转换为布尔值
使用按位的异或操作符(^ or operator.xor)
例如,
bool(a) ^ bool(b)
当您将输入转换为布尔值时,按位xor变成逻辑xor。
请注意,接受的答案是错误的:!=与Python中的xor不同,因为操作符链接非常微妙。
例如,下面三个值的xor在使用!=时是错误的:
True ^ False ^ False # True, as expected of XOR
True != False != False # False! Equivalent to `(True != False) and (False != False)`
(附注:我尝试编辑已接受的答案,以包含这一警告,但我的更改被拒绝了。)
你总是可以使用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