如何在 Python 中获得两个变量的逻辑异或?

发布于 2024-07-12 03:17:02 字数 652 浏览 6 评论 0原文

如何在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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(29

摘星┃星的人 2024-07-19 03:17:03

XOR 在operator.xor 中实现。

XOR is implemented in operator.xor.

无妨# 2024-07-19 03:17:03

Python 处理逻辑运算的方式可能会令人困惑,因此我的实现为用户提供了简单的 True/False 答案的选项(默认情况下)。 实际的 Python 结果可以通过将可选的第三个参数设置为 None 来获得。

def xor(a, b, true=True, false=False): # set true to None to get actual Python result
    ab1 = a and not b
    ab2 = not a and b
    if bool(ab1) != bool(ab2):
        return (ab1 or ab2) if true is None else true
    else:
        return false

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.

def xor(a, b, true=True, false=False): # set true to None to get actual Python result
    ab1 = a and not b
    ab2 = not a and b
    if bool(ab1) != bool(ab2):
        return (ab1 or ab2) if true is None else true
    else:
        return false
西瓜 2024-07-19 03:17:03
xor = ((False, True), (True, False)
eq = (xor[1], xor[0])

xor[False][True] # yields True

优点:

明确

使逻辑门上的操作可用

可以选择 (False, True), (0, 1) 等

如果需要,可以使用列表而不是元组

缺点:

非标准

主观上很愚蠢

性能可能比其他方法低

xor = ((False, True), (True, False)
eq = (xor[1], xor[0])

xor[False][True] # yields True

advantages:

explicit

makes operations on logic gates available

can frame as your choice of (False, True), (0, 1), and the such

can use lists rather than tuples if desired

.

disadvantages:

non-standard

subjectively goofy

plausibly less performant than other approaches

¢好甜 2024-07-19 03:17:03

我们可以通过使用以下方式轻松找到两个变量的异或:

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

示例:

<块引用>
<块引用>

异或(真,假)>> 正确


We can easily find xor of two variables by the using:

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

Example:

xor(True,False) >>> True

往昔成烟 2024-07-19 03:17:02

如果您已经将输入标准化为布尔值,则 != 是异或。

bool(a) != bool(b)

If you're already normalizing the inputs to booleans, then != is xor.

bool(a) != bool(b)
旧伤慢歌 2024-07-19 03:17:02

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

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

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

bool(a) ^ bool(b)

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

因此 tical_xor 函数的实现方式如下:

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

Credit to Nick Coghlan 在 Python-3000 邮件列表

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.

柠檬 2024-07-19 03:17:02

按位异或已经内置于 Python 中,位于 operator 模块(与 ^ 运算符相同):

from operator import xor
xor(bool(a), bool(b))  # Note: converting to bools is essential
重要提示

“请小心,这也是按位运算: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):

from operator import xor
xor(bool(a), bool(b))  # Note: converting to bools is essential
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 "

韬韬不绝 2024-07-19 03:17:02

正如扎克解释后,你可以使用:

xor = bool(a) ^ bool(b)

就我个人而言,我喜欢一种稍微不同的方言:

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

这种方言的灵感来自于我在学校学到的逻辑图表语言,其中“OR”由包含 ≥1 (大于或等于 1),“XOR”由包含 =1 的框表示。

这样做的优点是可以在多个操作数上正确实现独占或。

  • “1 = a ^ b ^ c...”表示真操作数的数量是奇数。 这个运算符就是“奇偶校验”。
  • “1 = a + b + c...”表示只有一个操作数为真。 这是“异或”,意思是“一个排除其他”。

As 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".
嘦怹 2024-07-19 03:17:02
  • Python 逻辑 orA 或 B:如果 bool(A)True,则返回 A code>,否则返回 B
  • Python 逻辑 andA 和 B:返回 A if bool( A)False,否则返回 B

为了保持大部分这种思维方式,我的逻辑异或定义是:

def logical_xor(a, b):
    if bool(a) == bool(b):
        return False
    else:
        return a or b

这样它就可以返回 abFalse

>>> logical_xor('this', 'that')
False
>>> logical_xor('', '')
False
>>> logical_xor('this', '')
'this'
>>> logical_xor('', 'that')
'that'
  • Python logical or: A or B: returns A if bool(A) is True, otherwise returns B
  • Python logical and: A and B: returns A if bool(A) is False, otherwise returns B

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'
多彩岁月 2024-07-19 03:17:02

我测试了多种方法(包括按照 ShadowRanger 建议使用 truth() 函数)。

%timeit  (not a) ^  (not b)   # 47 ns
%timeit  (not a) != (not b)   # 44.7 ns
%timeit truth(a) != truth(b)  # 116 ns
%timeit  bool(a) != bool(b)   # 190 ns

I've tested several approaches (including using the truth() function as ShadowRanger suggested).

%timeit  (not a) ^  (not b)   # 47 ns
%timeit  (not a) != (not b)   # 44.7 ns
%timeit truth(a) != truth(b)  # 116 ns
%timeit  bool(a) != bool(b)   # 190 ns
相守太难 2024-07-19 03:17:02

Python 有一个按位异或运算符,它是 ^

>>> True ^ False
True
>>> True ^ True
False
>>> False ^ True
True
>>> False ^ False
False

您可以通过在应用异或之前将输入转换为布尔值来使用它 (^):(

bool(a) ^ bool(b)

已编辑 - 感谢 Arel)

Python has a bitwise exclusive-OR operator, it's ^:

>>> True ^ False
True
>>> True ^ True
False
>>> False ^ True
True
>>> False ^ False
False

You can use it by converting the inputs to booleans before applying xor (^):

bool(a) ^ bool(b)

(Edited - thanks Arel)

与他有关 2024-07-19 03:17:02

简单,易于理解:

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

如果您想要的是排他性选择,即从 n 中选择 1 选项,它可以扩展到多个参数:

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

Simple, easy to understand:

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

If an exclusive choice is what you're after, i.e. to select 1 choice out of n, it can be expanded to multiple arguments:

sum(bool(x) for x in y) == 1
℡Ms空城旧梦 2024-07-19 03:17:02

要在 Python 中获取两个或多个变量的逻辑异或:

  1. 将输入转换为布尔值
  2. 使用按位异或运算符(^operator.xor

例如,

bool(a) ^ bool(b)

当您将输入到布尔值,按位异或变成逻辑异或。

请注意,接受的答案是错误的: != 与 Python 中的 xor 不同,因为运算符链的微妙之处。

例如,使用 != 时,以下三个值的异或是错误的:

True ^  False ^  False  # True, as expected of XOR
True != False != False  # False! Equivalent to `(True != False) and (False != False)`

(PS 我尝试编辑接受的答案以包含此警告,但我的更改被拒绝。)

To get the logical xor of two or more variables in Python:

  1. Convert inputs to booleans
  2. Use the bitwise xor operator (^ or operator.xor)

For example,

bool(a) ^ bool(b)

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 !=:

True ^  False ^  False  # True, as expected of XOR
True != False != False  # False! Equivalent to `(True != False) and (False != False)`

(P.S. I tried editing the accepted answer to include this warning, but my change was rejected.)

穿透光 2024-07-19 03:17:02

假设 A 和 B 是布尔值。

A is not B

Given that A and B are bools.

A is not B
淤浪 2024-07-19 03:17:02

由于我没有看到使用变量参数的 xor 的简单变体,并且仅对真值 True 或 False 进行操作,因此我将其放在这里供任何人使用。
正如其他人所指出的,非常(不是说非常)简单。

def xor(*vars):
    result = False
    for v in vars:
        result = result ^ bool(v)
    return result

用法也很简单:

if xor(False, False, True, False):
    print "Hello World!"

由于这是广义的 n 元逻辑 XOR,只要 True 操作数的数量为奇数,它的真值将为 True(并且不仅当恰好 1 为 True 时,这只是 n 的一种情况) -ary XOR 为真)。

因此,如果您正在搜索一个仅当其操作数之一为 True 时才为 True 的 n 元谓词,您可能需要使用:

def isOne(*vars):
    result = False
    for v in vars:
        if result and v:
            return False
        else:
            result = result or v
    return result

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.

def xor(*vars):
    result = False
    for v in vars:
        result = result ^ bool(v)
    return result

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):
    result = False
    for v in vars:
        if result and v:
            return False
        else:
            result = result or v
    return result
千纸鹤 2024-07-19 03:17:02

您使用与 C 中相同的 XOR 运算符,即 ^

我不知道为什么,但最受支持的解决方案建议 bool(A) != bool(B),而我会说 - 与 C 的 ^ 一致运算符,最明显的解决方案是:

bool(A) ^ bool(B)

对于来自 C 或任何 C 派生语言的任何人来说,这都更具可读性并且可以立即理解......

在进行代码高尔夫时,可能

not A ^ (not B)

将成为赢家。 使用 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:

bool(A) ^ bool(B)

which is more readable and immediately understandable for anyone coming from C or any C-derived language ...

when doing code-golfing, probably

not A ^ (not B)

will be the winner. with not as converter for boolean (one letter less than bool(). And for the first expression in some cases one can leave out the parantheses. Well, it depends, in cases where one has to do not(A) ^ (not(B)), the bool() needs same amount of letters ...

耳钉梦 2024-07-19 03:17:02

奖励线程:

另一个想法...只需尝试(可能是)Pythonic 表达式“不是”,以获得逻辑“异或”的行为

真值表将是:

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

抱歉我写的英文,这不是我的母语。

问候。

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:

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

And for your example string:

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

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.

霞映澄塘 2024-07-19 03:17:02

许多人,包括我自己,都需要一个类似于 n 输入异或电路的异或函数,其中 n 是可变的。 (请参阅https://en.wikipedia.org/wiki/XOR_gate)。 下面的简单函数实现了这一点。

def xor(*args):
   """
   This function accepts an arbitrary number of input arguments, returning True
   if and only if bool() evaluates to True for an odd number of the input arguments.
   """

   return bool(sum(map(bool,args)) % 2)

示例 I/O 如下:

In [1]: xor(False, True)
Out[1]: True

In [2]: xor(True, True)
Out[2]: False

In [3]: xor(True, True, True)
Out[3]: True

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.

def xor(*args):
   """
   This function accepts an arbitrary number of input arguments, returning True
   if and only if bool() evaluates to True for an odd number of the input arguments.
   """

   return bool(sum(map(bool,args)) % 2)

Sample I/O follows:

In [1]: xor(False, True)
Out[1]: True

In [2]: xor(True, True)
Out[2]: False

In [3]: xor(True, True, True)
Out[3]: True
少女七分熟 2024-07-19 03:17:02

我知道这已经晚了,但我有一个想法,这可能是值得的,只是为了记录。 也许这会起作用:np.abs(xy) 这个想法是,

  1. 如果 x=True=1 且 y=False=0 那么结果将是 |1-0|=1=True
  2. 如果 x =False=0 且 y=False=0 则结果为 |0-0|=0=False
  3. 如果 x=True=1 且 y=True=1 则结果为 |1-1|=0=False
  4. 如果 x=False=0 且 y=True=1 那么结果将是 |0-1|=1=True

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

  1. if x=True=1 and y=False=0 then the result would be |1-0|=1=True
  2. if x=False=0 and y=False=0 then the result would be |0-0|=0=False
  3. if x=True=1 and y=True=1 then the result would be |1-1|=0=False
  4. if x=False=0 and y=True=1 then the result would be |0-1|=1=True
绝對不後悔。 2024-07-19 03:17:02

异或定义如下

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

Exclusive Or is defined as follows

def xor( a, b ):
    return (a or b) and not (a and b)
十二 2024-07-19 03:17:02

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

也就是说,返回 TrueFalsexor 实现相当简单; 如果可能的话,返回操作数之一要棘手得多,因为对于应该选择哪个操作数还没有达成共识,尤其是当操作数超过两个时。 例如,xor(None, -1, [], True) 应该返回 None[]False >? 我敢打赌,每个答案对某些人来说都是最直观的。

对于 True 或 False 结果,有多达五种可能的选择:返回第一个操作数(如果它与值中的最终结果匹配,否则为布尔值),返回第一个匹配项(如果至少存在一个,否则为布尔值),返回最后一个操作数(if ... else ...),返回最后一个匹配项(if ... else ...),或者始终返回布尔值。 总共有 5 ** 2 = 25 种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()

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()
Spring初心 2024-07-19 03:17:02

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

z = (x + y) % 2

具有以下真值表:

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

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|
  -+-+-+
£噩梦荏苒 2024-07-19 03:17:02

这个怎么样?

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

如果 b 为 false,则给出 a
如果 a 为 false,则给出 b
否则将给出 False

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

(False if a else b) if b else a

How 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
李白 2024-07-19 03:17:02

Xor 在 Python 中是 ^。 它返回:

  • 整数的按位异或 布尔值的
  • 逻辑异或 集合的
  • 独占并集
  • 实现 __xor__ 的类的用户定义结果。
  • 未定义类型的 TypeError,例如字符串或字典。

如果您打算在字符串上使用它们,请将它们转换为 bool 使您的操作明确(您也可以指 set(str1) ^ set(str2))。

Xor is ^ in Python. It returns :

  • A bitwise xor for ints
  • Logical xor for bools
  • An exclusive union for sets
  • User-defined results for classes that implements __xor__.
  • TypeError for undefined types, such as strings or dictionaries.

If you intend to use them on strings anyway, casting them in bool makes your operation unambiguous (you could also mean set(str1) ^ set(str2)).

旧情别恋 2024-07-19 03:17:02

这就是我编写任何真值表的方法。 特别是对于异或,我们有:

| a | b  | xor   |             |
|---|----|-------|-------------|
| T | T  | F     |             |
| T | F  | T     | a and not b |
| F | T  | T     | not a and b |
| F | F  | F     |             |

只需查看答案列中的 T 值,并用逻辑或将所有真实情况串在一起。 因此,这个真值表可以在情况 2 或 3 中产生。因此,

xor = lambda a, b: (a and not b) or (not a and b)

This is how I would code up any truth table. For xor in particular we have:

| a | b  | xor   |             |
|---|----|-------|-------------|
| T | T  | F     |             |
| T | F  | T     | a and not b |
| F | T  | T     | not a and b |
| F | F  | F     |             |

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 = lambda a, b: (a and not b) or (not a and b)
长亭外,古道边 2024-07-19 03:17:02

异或 (XOR) 的含义可能会令人困惑,但可能会引导您到这里。

这是一个排他性检查,其功能类似于两个变量的 传统 XOR,但操作方式类似于 One-Hot 用于多个变量。

我在上面看到的唯一好处其他实现是它短路并且不那么神奇。

    def exclusive(*opts):
        count = 0
        for value in opts:
            if bool(value):  # If truthy
                count += 1
                if count > 1:  # Short-circuit
                    return False
        return count == 1  # Only Return True if one truthy found

以下是 XOR 和 ONE-HOT 之间差异的表格作为示例:

a|b|c|d --- xor|one-hot
-----------------------
0|0|0|0 --> 0  |0  
0|0|0|1 --> 1  |1  
0|0|1|0 --> 1  |1  
0|0|1|1 --> 0  |0  
0|1|0|0 --> 1  |1  
0|1|0|1 --> 0  |0  
0|1|1|0 --> 0  |0  
0|1|1|1 --> 1  |0  # noted difference
1|0|0|0 --> 1  |1  
1|0|0|1 --> 0  |0  
1|0|1|0 --> 0  |0  
1|0|1|1 --> 1  |0  # noted difference
1|1|0|0 --> 0  |0  
1|1|0|1 --> 1  |0  # noted difference
1|1|1|0 --> 1  |0  # noted difference
1|1|1|1 --> 0  |0

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.

    def exclusive(*opts):
        count = 0
        for value in opts:
            if bool(value):  # If truthy
                count += 1
                if count > 1:  # Short-circuit
                    return False
        return count == 1  # Only Return True if one truthy found

Here's a table of those differences between XOR and ONE-HOT as an example:

a|b|c|d --- xor|one-hot
-----------------------
0|0|0|0 --> 0  |0  
0|0|0|1 --> 1  |1  
0|0|1|0 --> 1  |1  
0|0|1|1 --> 0  |0  
0|1|0|0 --> 1  |1  
0|1|0|1 --> 0  |0  
0|1|1|0 --> 0  |0  
0|1|1|1 --> 1  |0  # noted difference
1|0|0|0 --> 1  |1  
1|0|0|1 --> 0  |0  
1|0|1|0 --> 0  |0  
1|0|1|1 --> 1  |0  # noted difference
1|1|0|0 --> 0  |0  
1|1|0|1 --> 1  |0  # noted difference
1|1|1|0 --> 1  |0  # noted difference
1|1|1|1 --> 0  |0
爱*していゐ 2024-07-19 03:17:02

当您知道 XOR 的作用时,这很容易:

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

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)))
泪之魂 2024-07-19 03:17:02

这是映射归约泛化的实现。 请注意,这相当于 functools.reduce(lambda x, y: x != y, map(bool, orands)) 。

def xor(*orands):
    return bool(sum(bool(x) for x in orands) % 2)

如果您正在寻找一款单热检测器,这里有一个概括。 这种概括可能适合英语中异或的使用(例如“用一美元你可以买一杯果汁或咖啡或茶”),但它与典型的操作顺序不符。 例如xor_1hot(1,1,1) == 0 != 1 == xor_1hot(xor_1hot(1,1),1)

def xor_1hot(*orands):
    return sum(bool(x) for x in orands) == 1

您可以使用

# test
from itertools import product
n = 3
total_true = 0
for inputs in product((False, True), repeat=n):
    y = xor(*inputs)
    total_true += int(y)
    print(f"{''.join(str(int(b)) for b in inputs)}|{y}")
print('Total True:', total_true)

One-Hot 检测器输出来测试其中之一:

000|错误
001|真实
010|正确
011|假
100|正确
101|错误
110|错误
111|错误
正确总数:3

Map-Reduce 输出:

000|错误
001|真实
010|真实
011|假
100|正确
101|错误
110|错误
111|正确
正确总数:4

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

def xor(*orands):
    return bool(sum(bool(x) for x in orands) % 2)

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

def xor_1hot(*orands):
    return sum(bool(x) for x in orands) == 1

You can test either with

# test
from itertools import product
n = 3
total_true = 0
for inputs in product((False, True), repeat=n):
    y = xor(*inputs)
    total_true += int(y)
    print(f"{''.join(str(int(b)) for b in inputs)}|{y}")
print('Total True:', total_true)

One-Hot Detector Output:

000|False
001|True
010|True
011|False
100|True
101|False
110|False
111|False
Total True: 3

Map-Reduce Output:

000|False
001|True
010|True
011|False
100|True
101|False
110|False
111|True
Total True: 4

神仙妹妹 2024-07-19 03:17:02

仅仅因为我没有在其他地方看到它提到过,这也能解决问题:

def logical_xor(a, b):
    return not b if a else bool(b)

我不确定它是否比公认的解决方案 bool(a) != bool(b) “更好”/更具可读性/更具Python风格。

Just because I haven't seen it mentioned elsewhere, this also does the trick:

def logical_xor(a, b):
    return not b if a else bool(b)

I'm not sure if it's "better"/more readable/more pythonic than the accepted solution bool(a) != bool(b).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文