python中xor是什么_python xor首选项:位运算符与布尔运算符

这篇博客探讨了在 Python 中执行逻辑异或操作的两种常见方法:位运算符 `^` 和布尔运算符 `(not a and b) or (a and not b)`。文章通过性能测试指出,布尔运算符的方法在效率上优于位运算符,尤其是在处理非布尔值时。此外,还讨论了代码的可读性和风格选择,建议根据实际需求和上下文来决定使用哪种方法。
摘要由CSDN通过智能技术生成

本问题已经有最佳答案,请猛点这里访问。

在python中,是否有一个执行逻辑异或的首选方法?

例如,如果我有两个变量a和b,并且我想检查至少有一个存在,但不是两个都存在,那么我有两个方法:

方法1(按位运算符):

if bool(a) ^ bool(b):

do x

方法2(布尔运算符):

if (not a and b) or (a and not b):

do x

使用这两种方法都有内在的性能优势吗?方法2看起来更像"Python",但方法1在我看来更干净。这个相关的线程似乎表明它可能首先取决于什么变量类型的a和b!

有什么有力的论据吗?

另一条线以什么方式不回答你的问题?如链接线程中详细说明的,这两个值并不相等。

"基本"?你的意思是"布尔",对吧?

@temporalwolf:python没有"xor"布尔运算符,我需要在编写的脚本中模拟这种行为。我特别询问两种不同的XOR实现的"pythonic"风格/性能。我知道它们不是等价的。

@板球007:是的,编辑。

"我想检查是否至少存在一个变量,但不能同时存在两个变量"-那么这两个选项都不存在,如果您试图检查变量是否存在,那么您可能选择了一种糟糕的方法来构造程序的这一部分。

@头晕,我会说,def xor(a, b): return (a and not b) or (b and not a)是最有可能的方法,然后在某些事情上称为xor(a, b),尽管这假设a和b是布尔值。如果需要的话,把它们包起来

@临时狼:我喜欢!

@头晕,值得一提的是,因为and具有更强的绑定能力,所以def xor(a, b): return a and not b or b and not a也可以工作,尽管可读性较差。

我不认为像用户自己提到的方法那样,将其标记为副本是个好主意。他更感兴趣的是应该优先选择哪一个以及为什么。

实现这一目标的另一种方法是使用any()和all(),如:

if any([a, b]) and not all([a, b]):

print"Either a or b is having value"

但根据性能,结果如下:

使用any()和all():每个回路0.542 usec

moin@moin-pc:~$ python -m"timeit""a='a';b='b';""any([a, b]) and not all([a, b])"

1000000 loops, best of 3: 0.542 usec per loop

使用bool(a) ^ bool(b):每个回路0.594 usec

moin@moin-pc:~$ python -m"timeit""a='a';b='b';""bool(a) ^ bool(b)"

1000000 loops, best of 3: 0.594 usec per loop

使用(not a and b) or (a and not b):每个回路0.0988 usec

moin@moin-pc:~$ python -m"timeit""a='a';b='b';""(not a and b) or (a and not b)"

10000000 loops, best of 3: 0.0988 usec per loop

显然,你的(not a and b) or (a and not b)更有效。效率大约是其他的6倍。

比较更多的and和or口味:

使用a and not b or b and not a(如temporalwolf所指):每个循环0.116 usec

moin@moin-pc:~$ python -m"timeit""a='a';b='b';""a and not b or b and not a"

10000000 loops, best of 3: 0.116 usec per loop

使用(a or b) and not (a and b):每个回路0.0951 usec

moin@moin-pc:~$ python -m"timeit""a='a';b='b';""(a or b) and not (a and b)"

10000000 loops, best of 3: 0.0951 usec per loop

注:本次业绩以a和b作为str的价值进行评价,取决于viraptor在评论中提到的__nonzero__和__bool__和__or__功能的实施情况。

a and not b or b and not a相当。and比or具有更强的结合力。

这取决于__nonzero__/__bool__/__or__的实施情况。对于str来说,这是微不足道的。对于一些远程调用的对象,它不是。OP没有提到所用的值。

@匿名的,我想你也可以看到and/or短路的好处:把它当作一个列表来理解只会把时间减半:for str in ("(bool(a) ^ bool(b))","any([a, b]) and not all([a, b])","a and not b or b and not a"): print timeit.timeit("[%s for a in range(2) for b in range(2)]" % str)。

@维拉普:同意你的看法。这完全取决于这些函数的实现。在回答中添加了您的评论

@temporalwolf:为您在回答中提到的表达式添加了timeit统计信息。

@匿名的,我更了解:你的时间它在做(等价的)a = True, b = True,这意味着当你运行and/or的例子时,第二部分永远不会运行,因为它短路:我发布的列表理解迫使它尝试所有四种逻辑组合,给出短路的好处的更好的近似值(而不是让它每次都这样)。如果您执行not a and b or not b and a,它将更快,因为这利用了True/True输入的短路。

您可以使它比将问题简化为XOR更具可读性。根据上下文,这些可能更好:

if sum((bool(a), bool(b))) == 1:  # this naturally extends to more values

if bool(a) != bool(b):

所以我认为最好的方法是使用与XOR背后的实际含义相匹配的内容。是否希望它们不具有相同的值?只有一套?还有别的吗?

如果你使用^,我在读代码,我假设你实际上想使用位运算符,这是有原因的。

Is there an inherent performance benefit to using either one?

这是一个声明。除非你知道这是性能问题,否则没关系。如果它在一个热循环中,并且你的分析器显示你确实需要优化它,那么你最好使用赛通或者其他加速它的方法。

在速度方面,从技术上讲,if (not a) is not (not b):会稍快一些,至少在cpython上相当于if bool(a) != bool(b):,因为not是语法(添加了UNARY_NOT指令),而bool添加了LOAD_GLOBAL和CALL_FUNCTION(两者都更昂贵)。切换到is not意味着您遵循的代码路径只处理身份平等,没有丰富的比较机制。

当然,但再次重申:"除非你知道这是一个性能问题,否则没关系。"我马上就知道bool(a)!=bool(b)所做的。我得花时间搞清楚(not a) is not (not b)是干什么的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值