如何在 Python 中获得两个变量的逻辑异或?
如何在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'
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 an 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 is bitwise, and not defined on all objects:
>>> 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'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(29)
XOR 在
operator.xor
中实现。XOR is implemented in
operator.xor
.Python 处理逻辑运算的方式可能会令人困惑,因此我的实现为用户提供了简单的 True/False 答案的选项(默认情况下)。 实际的 Python 结果可以通过将可选的第三个参数设置为 None 来获得。
The way that Python handles logic operations can be confusing, so my implementation gives the user the option (by default) of a simple True/False answer. The actual Python result can be obtained by setting the optional third arg to None.
优点:
。
缺点:
advantages:
.
disadvantages:
我们可以通过使用以下方式轻松找到两个变量的异或:
示例:
We can easily find xor of two variables by the using:
Example:
如果您已经将输入标准化为布尔值,则 != 是异或。
If you're already normalizing the inputs to booleans, then != is xor.
您始终可以使用 xor 的定义从其他逻辑运算中计算它:
但这对我来说有点太冗长了,乍一看并不是特别清楚。 另一种方法是:
两个布尔值上的异或运算符是逻辑异或(与整数不同,它是按位的)。 这是有道理的,因为
bool
只是一个子类int
,但实现为仅具有值0
和1
。 当域限制为0
和1
时,逻辑异或相当于按位异或。因此
tical_xor
函数的实现方式如下:Credit to Nick Coghlan 在 Python-3000 邮件列表。
You can always use the definition of xor to compute it from other logical operations:
But this is a little too verbose for me, and isn't particularly clear at first glance. Another way to do it is:
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 ofint
, but is implemented to only have the values0
and1
. And logical xor is equivalent to bitwise xor when the domain is restricted to0
and1
.So the
logical_xor
function would be implemented like:Credit to Nick Coghlan on the Python-3000 mailing list.
按位异或已经内置于 Python 中,位于
operator
模块(与^
运算符相同):重要提示
“请小心,这也是按位运算:xor(1, 2) 返回 3。来自文档字符串: xor(a, b) -- 与 a ^ b 相同。请记住,从运算符导入的任何内容都只是现有内置中缀运算符的函数形式 – Askewchan 2013 年 9 月 15 日,第 16 处: 59 ”
Bitwise exclusive-or is already built-in to Python, in the
operator
module (which is identical to the^
operator):IMPORTANT NOTE
"Be careful, this is also bitwise: 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, 2013 at 16:59 "
正如扎克解释后,你可以使用:
就我个人而言,我喜欢一种稍微不同的方言:
这种方言的灵感来自于我在学校学到的逻辑图表语言,其中“OR”由包含
≥1
(大于或等于 1),“XOR”由包含=1
的框表示。这样做的优点是可以在多个操作数上正确实现独占或。
As Zach explained, you can use:
Personally, I favor a slightly different dialect:
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.
or
:A 或 B
:如果bool(A)
为True
,则返回A
code>,否则返回B
and
:A 和 B
:返回A
ifbool( A)
是False
,否则返回B
为了保持大部分这种思维方式,我的逻辑异或定义是:
这样它就可以返回
a
、b
或False
:or
:A or B
: returnsA
ifbool(A)
isTrue
, otherwise returnsB
and
:A and B
: returnsA
ifbool(A)
isFalse
, otherwise returnsB
To keep most of that way of thinking, my logical xor definintion would be:
That way it can return
a
,b
, orFalse
:我测试了多种方法(包括按照 ShadowRanger 建议使用
truth()
函数)。I've tested several approaches (including using the
truth()
function as ShadowRanger suggested).Python 有一个按位异或运算符,它是
^
:您可以通过在应用异或之前将输入转换为布尔值来使用它 (
^
):(已编辑 - 感谢 Arel)
Python has a bitwise exclusive-OR operator, it's
^
:You can use it by converting the inputs to booleans before applying xor (
^
):(Edited - thanks Arel)
简单,易于理解:
如果您想要的是排他性选择,即从
n
中选择1
选项,它可以扩展到多个参数:Simple, easy to understand:
If an exclusive choice is what you're after, i.e. to select
1
choice out ofn
, it can be expanded to multiple arguments:要在 Python 中获取两个或多个变量的逻辑异或:
^
或operator.xor
)例如,
当您将输入到布尔值,按位异或变成逻辑异或。
请注意,接受的答案是错误的:
!=
与 Python 中的 xor 不同,因为运算符链的微妙之处。例如,使用
!=
时,以下三个值的异或是错误的:(PS 我尝试编辑接受的答案以包含此警告,但我的更改被拒绝。)
To get the logical xor of two or more variables in Python:
^
oroperator.xor
)For example,
When you convert the inputs to booleans, bitwise xor becomes logical xor.
Note that the accepted answer is wrong:
!=
is not the same as xor in Python because of the subtlety of operator chaining.For instance, the xor of the three values below is wrong when using
!=
:(P.S. I tried editing the accepted answer to include this warning, but my change was rejected.)
假设 A 和 B 是布尔值。
Given that A and B are bools.
由于我没有看到使用变量参数的 xor 的简单变体,并且仅对真值 True 或 False 进行操作,因此我将其放在这里供任何人使用。
正如其他人所指出的,非常(不是说非常)简单。
用法也很简单:
由于这是广义的 n 元逻辑 XOR,只要 True 操作数的数量为奇数,它的真值将为 True(并且不仅当恰好 1 为 True 时,这只是 n 的一种情况) -ary XOR 为真)。
因此,如果您正在搜索一个仅当其操作数之一为 True 时才为 True 的 n 元谓词,您可能需要使用:
As 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.
And usage is straightforward as well:
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:
您使用与 C 中相同的 XOR 运算符,即
^
。我不知道为什么,但最受支持的解决方案建议
bool(A) != bool(B)
,而我会说 - 与 C 的^
一致运算符,最明显的解决方案是:对于来自
C
或任何C
派生语言的任何人来说,这都更具可读性并且可以立即理解......在进行代码高尔夫时,可能
将成为赢家。 使用
not
作为布尔值转换器(比bool()
少一个字母。在某些情况下,对于第一个表达式,可以省略括号。好吧,这取决于,在在必须执行not(A) ^ (not(B))
的情况下,bool()
需要相同数量的字母...You use the same XOR operator like in C, which is
^
.I don't know why, but the most upvoted solution suggests
bool(A) != bool(B)
, while I would say - in conformity with C's^
's operator, the most obvious solution is:which is more readable and immediately understandable for anyone coming from
C
or anyC
-derived language ...when doing code-golfing, probably
will be the winner. with
not
as converter for boolean (one letter less thanbool()
. And for the first expression in some cases one can leave out the parantheses. Well, it depends, in cases where one has to donot(A) ^ (not(B))
, thebool()
needs same amount of letters ...奖励线程:
另一个想法...只需尝试(可能是)Pythonic 表达式“不是”,以获得逻辑“异或”的行为
真值表将是:
对于您的示例字符串:
但是; 正如他们上面指出的,这取决于您想要提取任何一对字符串的实际行为,因为字符串不是布尔值......甚至更多:如果您“深入研究Python”,您会发现““的特殊本质”和”和“或”»
http://www.diveintopython.net/power_of_introspection/and_or.html
抱歉我写的英文,这不是我的母语。
问候。
Rewarding thread:
Anoder idea... Just you try the (may be) pythonic expression «is not» in order to get behavior of logical «xor»
The truth table would be:
And for your example string:
However; as they indicated above, it depends of the actual behavior you want to pull out about any couple strings, because strings aren't boleans... and even more: if you «Dive Into Python» you will find «The Peculiar Nature of "and" and "or"»
http://www.diveintopython.net/power_of_introspection/and_or.html
Sorry my writed English, it's not my born language.
Regards.
许多人,包括我自己,都需要一个类似于 n 输入异或电路的异或函数,其中 n 是可变的。 (请参阅https://en.wikipedia.org/wiki/XOR_gate)。 下面的简单函数实现了这一点。
示例 I/O 如下:
Many folks, including myself, need an
xor
function that behaves like an n-input xor circuit, where n is variable. (See https://en.wikipedia.org/wiki/XOR_gate). The following simple function implements this.Sample I/O follows:
我知道这已经晚了,但我有一个想法,这可能是值得的,只是为了记录。 也许这会起作用:
np.abs(xy)
这个想法是,I know this is late, but I had a thought and it might be worth, just for documentation. Perhaps this would work:
np.abs(x-y)
The idea is that异或定义如下
Exclusive Or is defined as follows
这里建议的一些实现在某些情况下会导致操作数的重复求值,这可能会导致意想不到的副作用,因此必须避免。
也就是说,返回
True
或False
的xor
实现相当简单; 如果可能的话,返回操作数之一要棘手得多,因为对于应该选择哪个操作数还没有达成共识,尤其是当操作数超过两个时。 例如,xor(None, -1, [], True)
应该返回None
、[]
或False
>? 我敢打赌,每个答案对某些人来说都是最直观的。对于 True 或 False 结果,有多达五种可能的选择:返回第一个操作数(如果它与值中的最终结果匹配,否则为布尔值),返回第一个匹配项(如果至少存在一个,否则为布尔值),返回最后一个操作数(if ... else ...),返回最后一个匹配项(if ... else ...),或者始终返回布尔值。 总共有 5 ** 2 = 25 种
xor
。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 eitherTrue
orFalse
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, shouldxor(None, -1, [], True)
returnNone
,[]
orFalse
? 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
.有时我发现自己使用 1 和 0 而不是布尔 True 和 False 值。 在这种情况下,异或可以定义为
具有以下真值表:
Sometimes I find myself working with 1 and 0 instead of boolean True and False values. In this case xor can be defined as
which has the following truth table:
这个怎么样?
如果
b
为 false,则给出a
如果
a
为 false,则给出b
否则将给出
False
或者使用 Python 2.5+ 三元表达式:
How about this?
will give
a
ifb
is falsewill give
b
ifa
is falsewill give
False
otherwiseOr with the Python 2.5+ ternary expression:
Xor 在 Python 中是
^
。 它返回:__xor__
的类的用户定义结果。如果您打算在字符串上使用它们,请将它们转换为
bool
使您的操作明确(您也可以指set(str1) ^ set(str2)
)。Xor is
^
in Python. It returns :__xor__
.If you intend to use them on strings anyway, casting them in
bool
makes your operation unambiguous (you could also meanset(str1) ^ set(str2)
).这就是我编写任何真值表的方法。 特别是对于异或,我们有:
只需查看答案列中的 T 值,并用逻辑或将所有真实情况串在一起。 因此,这个真值表可以在情况 2 或 3 中产生。因此,
This is how I would code up any truth table. For xor in particular we have:
Just look at the T values in the answer column and string together all true cases with logical or. So, this truth table may be produced in case 2 or 3. Hence,
异或 (XOR) 的含义可能会令人困惑,但可能会引导您到这里。
这是一个排他性检查,其功能类似于两个变量的 传统 XOR,但操作方式类似于 One-Hot 用于多个变量。
我在上面看到的唯一好处其他实现是它短路并且不那么神奇。
以下是 XOR 和 ONE-HOT 之间差异的表格作为示例:
The meaning of Exclusive Or (XOR) can be confusing but may have lead you here.
Here is an exclusivity check that functions like the traditional XOR for two variables but operates like One-Hot for multiple variables.
The only benefit I can see above other implementations is that it short circuits and is less magical.
Here's a table of those differences between XOR and ONE-HOT as an example:
当您知道 XOR 的作用时,这很容易:
It's easy when you know what XOR does:
这是映射归约泛化的实现。 请注意,这相当于 functools.reduce(lambda x, y: x != y, map(bool, orands)) 。
如果您正在寻找一款单热检测器,这里有一个概括。 这种概括可能适合英语中异或的使用(例如“用一美元你可以买一杯果汁或咖啡或茶”),但它与典型的操作顺序不符。 例如
xor_1hot(1,1,1) == 0 != 1 == xor_1hot(xor_1hot(1,1),1)
。您可以使用
One-Hot 检测器输出来测试其中之一:
Map-Reduce 输出:
Here's an implementation of the map-reduce generalization. Note that this is equivalent to
functools.reduce(lambda x, y: x != y, map(bool, orands))
.Here's a generalization if you're looking for a one-hot detector. This generalization may fit the English language use of exclusive-or, (e.g. "For a dollar you can buy a juice or coffee or tea"), but it doesn't match the typical order of operations. E.g.
xor_1hot(1,1,1) == 0 != 1 == xor_1hot(xor_1hot(1,1),1)
.You can test either with
One-Hot Detector Output:
Map-Reduce Output:
仅仅因为我没有在其他地方看到它提到过,这也能解决问题:
我不确定它是否比公认的解决方案 bool(a) != bool(b) “更好”/更具可读性/更具Python风格。
Just because I haven't seen it mentioned elsewhere, this also does the trick:
I'm not sure if it's "better"/more readable/more pythonic than the accepted solution bool(a) != bool(b).