python xor首选项:位运算符与布尔运算符

Python XOR preference: bitwise operator vs. boolean operators

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

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

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

方法1(按位运算符):

1
2
if bool(a) ^ bool(b):
    do x

方法2(布尔运算符):

1
2
if (not a and b) or (a and not b):
    do x

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

有什么有力的论据吗?


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

1
2
if any([a, b]) and not all([a, b]):
    print"Either a or b is having value"

但根据性能,结果如下:

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

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

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

    1
    2
    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倍。

    比较更多的andor口味:

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

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

    1
    2
    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
  • 注:本次业绩以ab作为str的价值进行评价,取决于viraptor在评论中提到的__nonzero____bool____or__功能的实施情况。


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

    1
    2
    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?

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