python意思 - python运算符优先级




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

Exclusive Or定义如下

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

你如何获得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在operator.xor实现。


奖励线程:

阳光的想法...只是你尝试(可能)pythonic表达«不是»为了得到符合逻辑«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
>>> 

然而; 正如他们上面所指出的那样,它取决于你想要提取的任何字符串的实际行为,因为字符串不是布尔人......甚至更多:如果你“潜入Python”,你会发现“奇怪的性质”和“和”或“» http://www.diveintopython.net/power_of_introspection/and_or.html

对不起我的英文,这不是我的天生的语言。

问候。


如果你已经将输入标准化为布尔值,那么!=就是xor。

bool(a) != bool(b)

您始终可以使用xor的定义从其他逻辑运算中进行计算:

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

但是这对我来说有点过于冗长,乍一看并不是特别清楚。 另一种方法是:

bool(a) ^ bool(b)

两个布尔运算符上的异或运算符是逻辑异或(不同于整数,它是按位)。 这是有道理的,因为bool只是int一个子类 ,但实现为只有值01 。 当域被限制为01时,逻辑异或相当于异或。

所以logical_xor函数将被实现为:

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

感谢Python-3000邮件列表上的Nick Coghlan


我测试了几种方法,而not a != (not b)似乎是最快的。

这里有一些测试

%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

有时候我发现自己使用1和0而不是布尔True和False值。 在这种情况下,xor可以被定义为

z = (x + y) % 2

其中有以下真值表:

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

正如Zach解释的那样,您可以使用:

xor = bool(a) ^ bool(b)

就我个人而言,我赞成稍微不同的方言:

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

这种方言的灵感来自我在学校学到的逻辑图表语言,其中“OR”用包含≥1 (大于或等于1)的方框表示,“XOR”用包含=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)

如果b是假的,会给出答案
如果a是假的,会给b
否则将给出False

或者使用Python 2.5+三元表达式:

(False if a else b) if b else a

这里建议的一些实现会在某些情况下导致重复评估操作数,这可能会导致意想不到的副作用,因此必须避免。

也就是说,返回TrueFalsexor实现相当简单; 如果可能的话,返回其中一个操作数的操作非常棘手,因为对于哪个操作数应该是所选操作数没有共识,特别是当有多于两个操作数时。 例如,如果xor(None, -1, [], True)返回None[]False ? 我敢打赌,每个答案都是最直观的答案。

对于True或False结果,有多达五种可能的选择:返回第一个操作数(如果它匹配最终结果的值,否则为布尔值),返回第一个匹配(如果至少存在一个,则为布尔值),返回最后一个操作数(if ... else ...),返回最后一个匹配(if ... else ...),或者总是返回布尔值。 总的来说,这是5 ** 2 = xor 25种口味。

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()

通过使用我们可以很容易地找到两个变量的xor:

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

例:

xor(True,False)>>> True







logic