我正在project处理有关以下行的问题:
a == "EQUAL" or a == "NOT EQUAL" or a == "LESS" or a == "GREATER"
我提出了一个改变,让它更“简单”,如下:
a in ["EQUAL", "NOT EQUAL", "LESS", "GREATER"]
什么是最佳做法,什么是最佳表现?这适用于经常更新的用户界面代码,因此可以发现轻微的性能改进。我知道第一个例子将“快速失败”,如果找到任何一个,我假设第二个也是如此。
此外,使用像这样的词典会不会更快:
a in {"EQUAL", "NOT EQUAL", "LESS", "GREATER"}
...这样就不需要构建一个列表了吗?
PEP-8唯一说的(我能找到):
...代码的读取频率远高于编写代码。此处提供的准则旨在提高代码的可读性......
然而,知道何时不一致 - 有时风格指南建议不适用。如有疑问,请使用您的最佳判断。查看其他示例并确定最佳效果。
答案 0 :(得分:3)
我选择了套装。它更具可读性。 or
s字符串在某些情况下会更快,因为操作员短路并且每次都没有构建项目列表的开销,但我认为值得牺牲可读性。这是一个快速而肮脏的基准。这是使用Python 2.7
def t1(x):
return (x == "Foo" or x == "Bar" or x == "Baz" or x == "Quux")
def t2(x):
return x in {"Foo", "Bar", "Baz", "Quux"}
[2.7.9]>>> import timeit
[2.7.9]>>> timeit.timeit(lambda : t1("Quux"))
0.22514700889587402
[2.7.9]>>> timeit.timeit(lambda : t1("Foo"))
0.18890380859375
[2.7.9]>>> timeit.timeit(lambda : t2("Quux"))
0.27969884872436523
[2.7.9]>>> timeit.timeit(lambda : t2("Foo"))
0.25904297828674316
Python 3号码。
[3.4.2]>>> timeit.timeit(lambda : t1("Quux"))
0.25126787397312
[3.4.2]>>> timeit.timeit(lambda : t1("Foo"))
0.1722603400121443
[3.4.2]>>> timeit.timeit(lambda : t2("Quux"))
0.18982669000979513
[3.4.2]>>> timeit.timeit(lambda : t2("Foo"))
0.17984321201220155
答案 1 :(得分:1)
显然,在您的情况下,使用in
运算符会更好。它更具可读性。
在更复杂的情况下,如果无法使用in
运算符,您可以使用all
和any
函数:
operations = {'EQUAL', 'NOT EQUAL', 'LESS', 'GREATER'}
condition1 = any(curr_op.startswith(op) for op in operations)
condition2 = all([
self.Operation == "EQUAL",
isinstance(self.LeftHandSide, int),
isinstance(self.RightHandSide, int),
])
答案 2 :(得分:1)
正如多人所建议的那样,寻求恢复。
性能方面存在差异,集合上的in
运算符的平均查找时间为O(1),而对于列表,它是O(n)。你可以找到这个here。
在您的可能性列表有限的情况下,您几乎不会注意到差异。但是,一旦这个列表变得非常大(谈论数百万),你就会发现差异。
一个简单的例子可以显示:对于集合:
operation = 9999999
lookupSet = {i for i in range(0,10000000)}
%timeit operation in lookupSet
>> 10000000 loops, best of 3: 89.4 ns per loop
列表中的位置:
operation = 9999999
lookupList = [i for i in range(0,10000000)]
%timeit operation in lookupList
>> 10 loops, best of 3: 168 ms per loop