Python logical XOR
来源:互联网 发布:python find函数实现 编辑:程序博客网 时间:2024/06/06 17:41
How do you get the logical xor of two variables in Python?
For example, I have two variables that I expect to be strings. I want to test that only one of them contains a True value (is not None or the empty string):
str1 = raw_input("Enter string one:")str2 = raw_input("Enter string two:")if logical_xor(str1, str2): print "ok"else: print "bad"
The ^
operator seems to be bitwise, and not defined on all objects:
>>> 1 ^ 10>>> 2 ^ 13>>> "abc" ^ ""Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unsupported operand type(s) for ^: 'str' and 'str'
14 Answers
If you're already normalizing the inputs to booleans, then != is xor.
bool(a) != bool(b)
You can always use the definition of xor to compute it from other logical operations:
(a and not b) or (not a and b)
But this is a little too verbose for me, and isn't particularly clear at first glance. Another way to do it is:
bool(a) ^ bool(b)
The xor operator on two booleans is logical xor (unlike on ints, where it's bitwise). Which makes sense, since bool
is just a subclass of int
, but is implemented to only have the values 0
and 1
. And logical xor is equivalent to bitwise xor when the domain is restricted to 0
and 1
.
So the logical_xor
function would be implemented like:
def logical_xor(str1, str2): return bool(str1) ^ bool(str2)
Credit to Nick Coghlan on the Python-3000 mailing list.
(not b and a) or (not a and b)
so that it returns the string if there was one, which seems like the pythonic way for the function to operate. – rjmunro May 7 '11 at 21:06Exclusive-or is already built-in to Python, in the operator
module:
from operator import xorxor(bool(a), bool(b))
xor(1, 2)
returns 3
. From the docstring: xor(a, b) -- Same as a ^ b.
Remember that anything imported from operator
is just a functional form of an existing builtin infix operator. – askewchan Sep 15 '13 at 16:59 bool
type overloads __xor__
to return booleans. It'll work just fine, but its overkill when bool(a) ^ bool(b)
does exactly the same thing. – Martijn Pieters♦ Nov 3 '14 at 12:48As Zach explained, you can use:
xor = bool(a) ^ bool(b)
Personally, I favor a slightly different dialect:
xor = bool(a) + bool(b) == 1
This dialect is inspired from a logical diagramming language I learned in school where "OR" was denoted by a box containing ≥1
(greater than or equal to 1) and "XOR" was denoted by a box containing =1
.
This has the advantage of correctly implementing exclusive or on multiple operands.
- "1 = a ^ b ^ c..." means the number of true operands is odd. This operator is "parity".
- "1 = a + b + c..." means exactly one operand is true. This is "exclusive or", meaning "one to the exclusion of the others".
bool()
– BlueRaja - Danny Pflughoeft Apr 20 '10 at 13:26(((((True + True)==1)+False)==1)+True)==1
. The answer given here totally generalizes to multiple operands. – Mr. F Oct 23 '12 at 21:18- Python logical
or
:A or B
: returnsA
ifbool(A)
isTrue
, otherwise returnsB
- Python logical
and
:A and B
: returnsA
ifbool(A)
isFalse
, otherwise returnsB
To keep most of that way of thinking, my logical xor definintion would be:
def logical_xor(a, b): if bool(a) == bool(b): return False else: return a or b
That way it can return a
, b
, or False
:
>>> logical_xor('this', 'that')False>>> logical_xor('', '')False>>> logical_xor('this', '')'this'>>> logical_xor('', 'that')'that'
and
and or
won't return logical value. 'foo' and 'bar'
returns 'bar'
... – nosklo Feb 13 '11 at 2:11xor
implementation that is consistent with the built-in and
and or
. However, of course, in practical situations, bool(a) ^ bool(b)
or even a ^ b
(if a
and b
are known to be bool
) are more concise of course. – Erik Allik Jan 13 '12 at 13:48How about this?
(not b and a) or (not a and b)
will give a
if b
is false
will give b
if a
is false
will give False
otherwise
Or with the Python 2.5+ ternary expression:
(False if a else b) if b else a
Exclusive Or is defined as follows
def xor( a, b ): return (a or b) and not (a and b)
and
and or
do short-circuit. Any xor
implementation can't short-circuit, so there is already a discrepancy; therefore, there is no reason that xor
should operate like and
+or
do. – tzot Jan 11 '09 at 23:12As I don't see the simple variant of xor using variable arguments and only operation on Truth values True or False, I'll just throw it here for anyone to use. It's as noted by others, pretty (not to say very) straightforward.
def xor(*vars): sum = bool(False) for v in vars: sum = sum ^ bool(v) return sum
And usage is straightforward as well:
if xor(False, False, True, False): print "Hello World!"
As this is the generalized n-ary logical XOR, it's truth value will be True whenever the number of True operands is odd (and not only when exactly one is True, this is just one case in which n-ary XOR is True).
Thus if you are in search of a n-ary predicate that is only True when exactly one of it's operands is, you might want to use:
def isOne(*vars): sum = bool(False) for v in vars: if sum and v: return False else: sum = sum or v return sum
(bool(False) is False) == True
. You can just use False
on those lines. – lighttigersoul Apr 25 '15 at 6:01 Some of the implementations suggested here will cause repeated evaluation of the operands in some cases, which may lead to unintended side effects and therefore must be avoided.
That said, a xor
implementation that returns either True
or False
is fairly simple; one that returns one of the operands, if possible, is much trickier, because no consensus exists as to which operand should be the chosen one, especially when there are more than two operands. For instance, should xor(None, -1, [], True)
return None
, []
or False
? I bet each answer appears to some people as the most intuitive one.
For either the True- or the False-result, there are as many as five possible choices: return first operand (if it matches end result in value, else boolean), return first match (if at least one exists, else boolean), return last operand (if ... else ...), return last match (if ... else ...), or always return boolean. Altogether, that's 5 ** 2 = 25 flavors of xor
.
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()
It's easy when you know what XOR does:
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))
Sometimes I find myself working with 1 and 0 instead of boolean True and False values. In this case xor can be defined as
z = (x + y) % 2
which has the following truth table:
x |0|1| -+-+-+ 0|0|1|y -+-+-+ 1|1|0|
- Python logical XOR
- python中的xor运算
- python版xor解密源码
- xor
- XOR ^
- xor
- xor
- xor
- python bitwise and or operator VS logical operator
- Logical Databases Logical data
- Logical Lock
- logical分区
- logical database
- Logical DB
- Logical operator
- Logical Address
- Logical Architecture
- BP神经网络解决XOR异或运算python示例
- Python学习1_pip安装使用详解
- 第四周 项目4 程序分析(3)
- 在Ubuntu使用基于L2TP的VPN设置
- linux的scp命令可以在linux服务器之间复制文件和目录
- c++实验2-项目1标准体重
- Python logical XOR
- Leetcode 5. Longest Palindromic Substring
- 剑指 offer代码解析——面试题35第一个只出现一次的字符
- C++作业2
- 第一次跳槽之后的生活
- 第二次上机报告2-作业
- 70. Climbing Stairs
- Python Traverse list reverse order
- 将.hhc文件转换成html文件解析
a xor a
is defined as(a and not b) or (not a and b)
, and soa xor b
, whena
andb
are character strings, or any other types, should yield whatever(a and not b) or (not a and b)
yields. – Kaz May 14 '13 at 15:57