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

bool(a) != bool(b)

其他回答

很多人,包括我自己,都需要一个类似于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

我知道说这个有点晚了,但我有个想法也许值得,只是作为文档。也许这样可以: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

这就是我编写真值表的方法。对于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)

我已经测试了几种方法(包括使用shadow wranger建议的truth()函数)。

%timeit  (not a) ^  (not b)   # 47 ns
%timeit  (not a) != (not b)   # 44.7 ns
%timeit truth(a) != truth(b)  # 116 ns
%timeit  bool(a) != bool(b)   # 190 ns

因为我没有看到xor的简单变体使用变量参数,只对真值True或False进行操作,所以我只是把它扔在这里供任何人使用。 正如其他人所指出的,这相当(不是非常)直接。

def xor(*vars):
    result = False
    for v in vars:
        result = result ^ bool(v)
    return result

用法也很简单:

if xor(False, False, True, False):
    print "Hello World!"

由于这是广义n元逻辑异或,当True操作数的数量为奇数时,它的真值将为True(不仅仅是当恰好有一个为True时,这只是n元异或为True的一种情况)。

因此,如果你在搜索一个n-ary谓词,当它的一个操作数恰好为True时,它才为True,你可能想使用:

def isOne(*vars):
    result = False
    for v in vars:
        if result and v:
            return False
        else:
            result = result or v
    return result