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

2025-01-08 08:50:00
admin
原创
121
摘要:问题描述:在 Python 中如何获取两个变量的逻辑异或?例如,我有两个变量,我希望它们是字符串。我想测试其中只有一个包含 True 值(不是 None 或空字符串):str1 = raw_input("Enter string one:") str2 = raw_input("...

问题描述:

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

解决方案 1:

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

bool(a) != bool(b)

解决方案 2:

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

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

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

bool(a) ^ bool(b)

两个布尔值上的异或运算符是逻辑异或(与 int 不同,后者是按位异或)。这是有道理的,因为bool只是 的一个子类int,但实现为仅具有值0和。当域限制为和 时1,逻辑异或等同于按位异或。0`1`

因此该logical_xor函数的实现如下:

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

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

解决方案 3:

按位排他或已经内置到 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”

解决方案 4:

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

xor = bool(a) ^ bool(b)

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

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

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

这样做的好处是能够正确实现多个操作数的排他或运算。

  • “1 = a^b^c...” 表示真操作数的个数为奇数。此运算符为“奇偶校验”。

  • “1 = a + b + c...” 表示只有一个操作数为真。这是“排他或”,意思是“一个排除其他”。

解决方案 5:

  • Python 逻辑or::如果是则A or B返回,否则返回A`bool(A)TrueB`

  • Python 逻辑and::如果是则A and B返回,否则返回A`bool(A)FalseB`

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

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'

解决方案 6:

我测试了几种方法(包括使用truth()ShadowRanger 建议的功能)。

%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

解决方案 7:

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

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

您可以在应用 xor() 之前将输入转换为布尔值来使用它^

bool(a) ^ bool(b)

(已编辑 - 感谢 Arel)

解决方案 8:

简单、易于理解:

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

如果您想要的是独占选择,即1从中选择n,则可以将其扩展为多个参数:

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

解决方案 9:

要在 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:我尝试编辑已接受的答案以包含此警告,但我的更改被拒绝了。)

解决方案 10:

假设 A 和 B 是布尔值。

A is not B

解决方案 11:

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

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(并且不仅当恰好有一个为 True 时,这只是 n 元 XOR 为 True 的一种情况)。

因此,如果您要搜索一个仅当其操作数之一为 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

解决方案 12:

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

我不知道为什么,但最受欢迎的解决方案建议bool(A) != bool(B),而我想说 - 符合 C 的^运算符,最明显的解决方案是:

bool(A) ^ bool(B)

C对于来自或衍生语言的人来说,它更具可读性并且可以立即理解C......

在玩代码高尔夫的时候,可能

not A ^ (not B)

将是赢家。使用not作为布尔值的转换器(比少一个字母bool()。并且对于第一个表达式,在某些情况下可以省略括号。嗯,这取决于在必须做的情况下not(A) ^ (not(B))bool()需要相同数量的字母......

解决方案 13:

悬赏帖:

另一个想法...你只需尝试(可能是)pythonic表达式«is not»,以获得逻辑«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》,您会发现《“and”和“or”的特殊性质》
http://www.diveintopython.net/power_of_introspection/and_or.html

抱歉,我的书面英语不是我的母语。

问候。

解决方案 14:

包括我自己在内的许多人都需要一个xor像 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

解决方案 15:

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

  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

解决方案 16:

排他或定义如下

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

解决方案 17:

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

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

对于 True 或 False 结果,有多达五种可能的选择:返回第一个操作数(如果它与最终结果的值匹配,否则为布尔值)、返回第一个匹配项(如果至少存在一个,否则为布尔值)、返回最后一个操作数(如果 ... 否则 ...)、返回最后一个匹配项(如果 ... 否则 ...),或者始终返回布尔值。总共有 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)    t: %d (%s)    x: %s' % (f, choices[f], t, choices[t], x))
  print()

解决方案 18:

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

z = (x + y) % 2

其真值表如下:

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

解决方案 19:

这个怎么样?

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

a如果b为假则给予如果为假则

给予否则
给予b`a`
False

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

(False if a else b) if b else a

解决方案 20:

Xor 是^Python 中的函数。它返回:

  • 对整数进行按位异或

  • 布尔值的逻辑异或

  • 集合的专属联合

  • 实现的类的用户定义结果__xor__

  • 对于未定义类型(例如字符串或字典)会出现 TypeError。

如果您无论如何都打算在字符串上使用它们,则将它们强制转换bool会使您的操作变得明确(您也可以意味着set(str1) ^ set(str2))。

解决方案 21:

这就是我编写真值表的方法。具体来说,对于异或,我们有:

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

解决方案 22:

排他或(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

解决方案 23:

如果你知道 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)))

解决方案 24:

这是 map-reduce 泛化的实现。请注意,这相当于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)

独热检测器输出:

000|假

001|正确

010|正确

011|错误

100|正确

101|错误

110|错误

111|错误

正确总数:3

Map-Reduce 输出:

000|假

001|真

010|真

011|假

100|真

101|假

110|假

111|真

总计真数:4

解决方案 25:

只是因为我没有在其他地方看到过它,但这也能起到作用:

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

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

解决方案 26:

XOR 在 中实现operator.xor

解决方案 27:

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

xor[False][True] # yields True

优点:

明确的

使逻辑门操作可用

可以将其定义为(False,True)、(0,1)等

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

缺点:

非标准

主观上愚蠢

可能比其他方法性能更差

解决方案 28:

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

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

解决方案 29:

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

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

例子:

xor(True,False) >>> True

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用