使用 "if x in (y, z)" 会比 "if x == y or x == z" 更好吗?
Would it be better to use "if x in (y, z)" over "if x == y or x == z"?
鉴于这个简单的条件:
if x == y or x == z:
print("Hello World!");
我知道 Python 会先看看 x
是否等于 y
并且 x
是否 不 等于 y
然后它会检查 x
是否等于 z
,如果至少有一个条件是 True
,则打印 Hello World!
。
如果我改为这样做:
if x in (y, z):
print("Hello World!");
据我了解,Python 将遍历 "yz" 元组,然后如果 x
的值在 "yz" 元组中,则打印 Hello World!
。
哪种方法使用起来更快/更有效?
如果 x
等于 y
,Python 会不会费心检查 x
是否等于 z
?
如果 x
等于 y
但 不 z
?[=31=,Python 是否仍会执行 if 语句中的代码]
提前谢谢你。
我愿意 if x == y or x == z
:
您可以利用以下事实:如果 x == y
.
[=30,x == z
将 不会 被计算=]
创建匿名临时元组可能是一项开销。
if x == y or x == z
在其他语言中也很常见,因此可能更具可读性。
也许好的 python 解释器可以优化匿名临时文件。
我知道python是个懒惰的语言,他不需要检查第二个语句。但是我不知道你的其他方法是否会更快。
Would Python not bother to check if x was equal to z if x was equal to y?
是的,Python不会检查它。
Would Python still execute the code in the if statement if x was equal to y but not z
不,他不会。
两个选择,第一个可读性更强,二十个,第二个。性能不是真正的问题。
让我们自己测试一下。
这里有一个 class 重载了相等运算符,让我们看看 Python 在做什么:
class Foo:
def __init__(self, name):
self.name = name
def __eq__(self, other):
print self.name, "==", other.name, "?"
return self.name == other.name
让我们测试一下短路:
# x and a are passed the same string because we want x == a to be True
x = Foo("a")
a, b = Foo("a"), Foo("b")
if x in (a, b):
print "Hello World!"
对我来说,输出:
a == a ?
Hello World!
a == b ?
未打印,因此短路确实按预期工作。该块也按需要执行。
现在是速度。如果我们将上面的 __eq__
方法修改为 删除打印语句(以避免在我们的基准测试中使用 I/O) 并使用 IPython 的 %timeit
魔法命令,我们可以这样测试:
c = Foo("c") # for comparison when x is not equal to either case
%timeit x in (a, b) # equal to first case
%timeit (x == a or x == b)
%timeit x in (b, a) # equal to second case
%timeit (x == b or x == a)
%timeit x in (b, c) # not equal to either case
%timeit (x == b or x == c)
这些是每次迭代的平均次数(来自 100 万次迭代):
Code Time (ns)
x in (a, b) 437
x == a or x == b 397
x in (b, a) 796
x == b or x == a 819
x in (b, c) 779
x == b or x == c 787
所以,相当可比的结果。有细微差别,但还不足以让您担心。根据具体情况使用最易读的那个。
当只有两个选项时,这实际上只是基于意见,但我想指出,如果您需要检查 x
与说 5 个值,将会有更大的差异:
if x == a or x == b or x == c or x == d or x == e:
对比:
if x in (a,b,c,d,e):
特别是如果您稍后需要将其更改为 not in
与所有 ==
到 !=
相比,第二个似乎更容易扩展。
鉴于这个简单的条件:
if x == y or x == z:
print("Hello World!");
我知道 Python 会先看看 x
是否等于 y
并且 x
是否 不 等于 y
然后它会检查 x
是否等于 z
,如果至少有一个条件是 True
,则打印 Hello World!
。
如果我改为这样做:
if x in (y, z):
print("Hello World!");
据我了解,Python 将遍历 "yz" 元组,然后如果 x
的值在 "yz" 元组中,则打印 Hello World!
。
哪种方法使用起来更快/更有效?
如果 x
等于 y
,Python 会不会费心检查 x
是否等于 z
?
如果 x
等于 y
但 不 z
?[=31=,Python 是否仍会执行 if 语句中的代码]
提前谢谢你。
我愿意 if x == y or x == z
:
您可以利用以下事实:如果
[=30,x == y
.x == z
将 不会 被计算=]创建匿名临时元组可能是一项开销。
if x == y or x == z
在其他语言中也很常见,因此可能更具可读性。
也许好的 python 解释器可以优化匿名临时文件。
我知道python是个懒惰的语言,他不需要检查第二个语句。但是我不知道你的其他方法是否会更快。
Would Python not bother to check if x was equal to z if x was equal to y?
是的,Python不会检查它。
Would Python still execute the code in the if statement if x was equal to y but not z
不,他不会。
两个选择,第一个可读性更强,二十个,第二个。性能不是真正的问题。
让我们自己测试一下。
这里有一个 class 重载了相等运算符,让我们看看 Python 在做什么:
class Foo:
def __init__(self, name):
self.name = name
def __eq__(self, other):
print self.name, "==", other.name, "?"
return self.name == other.name
让我们测试一下短路:
# x and a are passed the same string because we want x == a to be True
x = Foo("a")
a, b = Foo("a"), Foo("b")
if x in (a, b):
print "Hello World!"
对我来说,输出:
a == a ?
Hello World!
a == b ?
未打印,因此短路确实按预期工作。该块也按需要执行。
现在是速度。如果我们将上面的 __eq__
方法修改为 删除打印语句(以避免在我们的基准测试中使用 I/O) 并使用 IPython 的 %timeit
魔法命令,我们可以这样测试:
c = Foo("c") # for comparison when x is not equal to either case
%timeit x in (a, b) # equal to first case
%timeit (x == a or x == b)
%timeit x in (b, a) # equal to second case
%timeit (x == b or x == a)
%timeit x in (b, c) # not equal to either case
%timeit (x == b or x == c)
这些是每次迭代的平均次数(来自 100 万次迭代):
Code Time (ns)
x in (a, b) 437
x == a or x == b 397
x in (b, a) 796
x == b or x == a 819
x in (b, c) 779
x == b or x == c 787
所以,相当可比的结果。有细微差别,但还不足以让您担心。根据具体情况使用最易读的那个。
当只有两个选项时,这实际上只是基于意见,但我想指出,如果您需要检查 x
与说 5 个值,将会有更大的差异:
if x == a or x == b or x == c or x == d or x == e:
对比:
if x in (a,b,c,d,e):
特别是如果您稍后需要将其更改为 not in
与所有 ==
到 !=
相比,第二个似乎更容易扩展。