你如何得到Python中两个variables的逻辑异或?
你如何得到Python中两个variables的逻辑异或?
例如,我有两个variables,我希望是string。 我想testing它们中只有一个包含True值(不是None或空string):
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' 
	
如果你已经把input标准化为布尔值,那么!=是xor。
 bool(a) != bool(b) 
您始终可以使用xor的定义从其他逻辑运算中进行计算:
 (a and not b) or (not a and b) 
但是这对我来说有点过于冗长,乍一看不是很清楚。 另一种方法是:
 bool(a) ^ bool(b) 
 两个布尔值上的异或运算符是逻辑异或(不同于整数,它是按位)。 这是有道理的,因为bool只是int一个子类 ,但实现只有值0和1 。 而逻辑xor相当于当域被限制为0和1时按位异或。 
 所以logical_xor函数将被实现如下: 
 def logical_xor(str1, str2): return bool(str1) ^ bool(str2) 
感谢Python-3000邮件列表上的Nick Coghlan 。
 在operator模块中独占或已经内置到Python中: 
 from operator import xor xor(bool(a), bool(b)) 
正如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 …”意味着只有一个操作数是真的。 这是“排他性”,意思是“排除其他”。
-   Python逻辑or:A or B:如果bool(A)为True则返回B,否则返回B
-   Python逻辑and:A and B:如果bool(A)为False则返回B,否则返回B
为了保持大部分的思维方式,我的逻辑xor definintion将是:
 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' 
 我testing了几种方法,而not a != (not b)似乎是最快的。 
这里有一些testing
 %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 
Exclusive Or定义如下
 def xor( a, b ): return (a or b) and not (a and b) 
由于我没有看到使用variables参数的xor的简单变体,只有在真值True或False上的操作,我只是把它放在这里供任何人使用。 正如其他人所指出的,漂亮(不是很直白)。
 def xor(*vars): sum = bool(False) for v in vars: sum = sum ^ bool(v) return sum 
用法也很简单:
 if xor(False, False, True, False): print "Hello World!" 
由于这是广义的n元逻辑XOR,只要True操作数的数目是奇数(而不是只有当一个是True时,这只是n元XOR为真的一种情况),真值就是真。
因此,如果你正在寻找只有当它的一个操作数是真的n元谓词时,你可能想要使用:
 def isOne(*vars): sum = bool(False) for v in vars: if sum and v: return False else: sum = sum or v return sum 
这个怎么样?
 (not b and a) or (not a and b) 
 会给出a如果b是假的 
 如果a是假的,会给b 
 否则会给出False 
或者用Python 2.5+三元expression式:
 (False if a else b) if b else a 
这里build议的一些实现会在某些情况下引起操作数的重复评估,这可能会导致意想不到的副作用,因此必须避免。
 也就是说,返回True或False的xor实现相当简单; 如果可能的话,返回其中一个操作数的操作非常棘手,因为对于哪个操作数应该是所选操作数没有共识,特别是当有多于两个的操作数时。 例如,如果xor(None, -1, [], True)返回None , []或False ? 我敢打赌,每个答案都是最直观的答案。 
对于True或False结果,有五种可能的select:返回第一个操作数(如果它匹配最终结果的值,否则布尔),返回第一个匹配(如果至less有一个存在,否则布尔),返回最后一个操作数(if … else …),返回最后一个匹配(if … else …),或者总是返回布尔值。 总的来说,这是5 ** 2 = 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() 
当你知道异或的时候很容易:
 def logical_xor(a, b): return (a and not b) or (not a and b) test_data = [ [False, False], [False, True], [True, False], [True, True], ] for a, b in test_data: print '%r xor %s = %r' % (a, b, logical_xor(a, b)) 
  XOR在operator.xor实现。 
奖励线程:
阳光的想法…只是你尝试(可能)pythonicexpression«不是»为了得到符合逻辑«xor»的行为
真理表将是:
 >>> True is not True False >>> True is not False True >>> False is not True True >>> False is not False False >>> 
和你的例子string:
 >>> "abc" is not "" True >>> 'abc' is not 'abc' False >>> 'abc' is not '' True >>> '' is not 'abc' True >>> '' is not '' False >>> 
然而; 正如他们上面所指出的那样,它取决于你想要提取的任何string的实际行为,因为string不是布尔人……甚至更多:如果你“潜入Python”,你会发现“奇怪的性质”和“和”或“» http://www.diveintopython.net/power_of_introspection/and_or.html
对不起我的英文,这不是我的天生的语言。
问候。
 我知道这是迟到,但我有一个想法,这可能是值得的,只是为了文件。 也许这会工作: np.abs(xy)这个想法是 
- 如果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
有时我发现自己正在使用1和0而不是布尔True和False值。 在这种情况下,xor可以被定义为
 z = (x + y) % 2 
其中有以下真值表:
  x |0|1| -+-+-+ 0|0|1| y -+-+-+ 1|1|0| -+-+-+ 
这将获得两个(或更多)variables的逻辑异或异或
 str1 = raw_input("Enter string one:") str2 = raw_input("Enter string two:") any([str1, str2]) and not all([str1, str2]) 
这个设置的第一个问题是,它最有可能遍历整个列表两次,至less会检查至less一个元素两次。 所以它可能会增加代码的理解力,但是它不会提高速度(根据您的使用情况可能会有所不同)。
这个设置的第二个问题是,无论variables数量多less,它都会检查排他性。 这可能首先被认为是一个特征,但随着variables数量增加(如果它们曾经这样做),第一个问题变得更加重要。
简单,容易理解:
 sum( (bool(a), bool(b) ) == 1 
如果一个排他性的select是你以后,它可以扩展到多个参数:
 sum( bool(x) for x in y ) == 1