Python XOR首选项:按位运算符与布尔运算符

时间:2016-10-17 22:22:38

标签: python xor

是否有一种在python中进行逻辑XOR的首选方法?

例如,如果我有两个变量a和b,并且我想检查至少有一个变量而不是两个变量,我有两种方法:

方法1(按位运算符):

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

方法2(布尔运算符):

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

使用其中任何一个都有固有的性能优势吗?方法2似乎更多" pythonic" 但方法1对我来说看起来更干净。这个related thread似乎表明它可能取决于ab变量类型的位置!

任何强有力的论据?

2 个答案:

答案 0 :(得分:1)

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

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

但根据表现,以下是结果:

  1. 使用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
    
  2. 使用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
    
  3. 每个循环使用(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
    
  4. 显然,您的 (not a and b) or (a and not b) 效率更高。效率大约是其他人的6倍。

    andor的几种风格之间的比较:

    1. 使用a and not b or b and not a(由 TemporalWolf指定):每个循环使用0.116个

      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
      
    2. 每个循环使用(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
      
    3. 注意:此效果的评估值为ab str,并取决于__nonzero__的实施情况/ __bool__ / __or__ 函数,如评论中 viraptor 所述。

答案 1 :(得分:0)

除了将问题减少到XOR之外,您可以使其更具可读性。根据具体情况,这可能会更好:

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

所以我认为最好的方法是选择与XOR背后的实际含义相匹配的东西。你想让他们没有相同的价值吗?只有其中一个设置?还有别的吗?

如果您使用^并且我正在阅读代码,我将假设您实际上想要使用按位运算符,并且由于某种原因这很重要。

  

使用其中任何一个都有固有的性能优势吗?

这是一个声明。除非你知道它是性能问题,否则无所谓。如果它处于热循环中并且您的探查器显示您确实需要对其进行优化,那么您最好使用Cython或其他一些加速它的方法。