Python XOR 偏好:按位运算符与布尔运算符
Python XOR preference: bitwise operator vs. boolean operators
是否有在 python 中进行逻辑异或的首选方法?
例如,如果我有两个变量 a 和 b,并且我想检查是否至少存在一个而不是两个都存在,我有两种方法:
方法一(按位运算符):
if bool(a) ^ bool(b):
do x
方法二(布尔运算符):
if (not a and b) or (a and not b):
do x
使用其中任何一个都有固有的性能优势吗?方法 2 似乎更 "pythonic" 但方法 1 对我来说看起来更干净。这个related thread似乎表明它可能首先取决于a
和b
是什么变量类型!
有任何有力的论据吗?
与将问题简化为 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?
这是一个声明。除非您知道这是性能问题,否则没关系。如果它处于热循环中并且您的探查器显示您确实需要对其进行优化,那么您最好使用 Cython 或其他一些加速方法。
另一种实现方法是使用 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 微秒
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 微秒
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
,并依赖于实现__nonzero__
/ __bool__
/ __or__
functions 正如 viraptor 在评论中提到的那样。
是否有在 python 中进行逻辑异或的首选方法?
例如,如果我有两个变量 a 和 b,并且我想检查是否至少存在一个而不是两个都存在,我有两种方法:
方法一(按位运算符):
if bool(a) ^ bool(b):
do x
方法二(布尔运算符):
if (not a and b) or (a and not b):
do x
使用其中任何一个都有固有的性能优势吗?方法 2 似乎更 "pythonic" 但方法 1 对我来说看起来更干净。这个related thread似乎表明它可能首先取决于a
和b
是什么变量类型!
有任何有力的论据吗?
与将问题简化为 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?
这是一个声明。除非您知道这是性能问题,否则没关系。如果它处于热循环中并且您的探查器显示您确实需要对其进行优化,那么您最好使用 Cython 或其他一些加速方法。
另一种实现方法是使用 any()
和 all()
,例如:
if any([a, b]) and not all([a, b]):
print "Either a or b is having value"
但根据性能,结果如下:
使用
any()
和all()
:每个循环0.542 usecmoin@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 微秒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 微秒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 usecmoin@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 usecmoin@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
,并依赖于实现__nonzero__
/ __bool__
/ __or__
functions 正如 viraptor 在评论中提到的那样。