如何在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'
这是映射-缩减泛化的实现。注意,这相当于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
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'