# python意思 - python运算符优先级

## 你如何获得Python中两个变量的逻辑异或? (12)

Exclusive Or定义如下

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

``````str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")
if logical_xor(str1, str2):
print "ok"
else:
``````

`^`运算符似乎是按位，并且没有在所有对象上定义：

``````>>> 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在`operator.xor`实现。

``````>>> True is not True
False
>>> True is not False
True
>>> False is not True
True
>>> False is not False
False
>>>
``````

``````>>> "abc" is not  ""
True
>>> 'abc' is not 'abc'
False
>>> 'abc' is not ''
True
>>> '' is not 'abc'
True
>>> '' is not ''
False
>>>
``````

``````bool(a) != bool(b)
``````

``````(a and not b) or (not a and b)
``````

``````bool(a) ^ bool(b)
``````

``````def logical_xor(str1, str2):
return bool(str1) ^ bool(str2)
``````

``````%timeit not a != (not b)
10000000 loops, best of 3: 78.5 ns per loop

In [130]: %timeit bool(a) != bool(b)
1000000 loops, best of 3: 343 ns per loop

In [131]: %timeit not a ^ (not b)
10000000 loops, best of 3: 131 ns per loop
``````

``````z = (x + y) % 2
``````

``````     x
|0|1|
-+-+-+
0|0|1|
y -+-+-+
1|1|0|
-+-+-+
``````

``````xor = bool(a) ^ bool(b)
``````

``````xor = bool(a) + bool(b) == 1
``````

• “1 = a ^ b ^ c ...”表示真实操作数的数目是奇数。 这个操作符是“奇偶校验”。
• “1 = a + b + c ...”意味着只有一个操作数是真的。 这是“排他性”，意思是“排除其他”。

``````sum( (bool(a), bool(b) ) == 1
``````

``````sum( bool(x) for x in y ) == 1
``````

``````(not b and a) or (not a and b)
``````

``````(False if a else b) if b else a
``````

``````def xor(*operands, falsechoice = -2, truechoice = -2):
"""A single-evaluation, multi-operand, full-choice xor implementation
falsechoice, truechoice: 0 = always bool, +/-1 = first/last operand, +/-2 = first/last match"""
if not operands:
raise TypeError('at least one operand expected')
choices = [falsechoice, truechoice]
matches = {}
result = False
first = True
value = choice = None
# avoid using index or slice since operands may be an infinite iterator
for operand in operands:
# evaluate each operand once only so as to avoid unintended side effects
value = bool(operand)
# the actual xor operation
result ^= value
# choice for the current operand, which may or may not match end result
choice = choices[value]
# if choice is last match;
# or last operand and the current operand, in case it is last, matches result;
# or first operand and the current operand is indeed first;
# or first match and there hasn't been a match so far
if choice < -1 or (choice == -1 and value == result) or (choice == 1 and first) or (choice > 1 and value not in matches):
# store the current operand
matches[value] = operand
# next operand will no longer be first
first = False
# if choice for result is last operand, but they mismatch
if (choices[result] == -1) and (result != value):
return result
else:
# return the stored matching operand, if existing, else result as bool
return matches.get(result, result)

testcases = [
(-1, None, True, {None: None}, [], 'a'),
(None, -1, {None: None}, 'a', []),
(None, -1, True, {None: None}, 'a', []),
(-1, None, {None: None}, [], 'a')]
choices = {-2: 'last match', -1: 'last operand', 0: 'always bool', 1: 'first operand', 2: 'first match'}
for c in testcases:
print(c)
for f in sorted(choices.keys()):
for t in sorted(choices.keys()):
x = xor(*c, falsechoice = f, truechoice = t)
print('f: %d (%s)\tt: %d (%s)\tx: %s' % (f, choices[f], t, choices[t], x))
print()
``````

``````def xor(a,b):
return a !=b
``````

xor（True，False）>>> True