这里有一个比较笼统的问题:python中应该在什么情况下使用内置模块?operator
最佳答案声称operator.itemgetter(x)
比大概比“更整洁” lambda a: a[x]
。我觉得恰恰相反。
还有其他好处吗,比如性能?
这里有一个比较笼统的问题:python中应该在什么情况下使用内置模块?operator
最佳答案声称operator.itemgetter(x)
比大概比“更整洁” lambda a: a[x]
。我觉得恰恰相反。
还有其他好处吗,比如性能?
除非您的代码处于紧密的内部循环中,否则您不应该担心性能,这实际上是一个性能问题。相反,请使用最能表达您意图的代码。有些人喜欢 lambdas,有些人喜欢 itemgetter。有时这只是口味问题。
itemgetter
更强大,例如,如果您需要一次获取多个元素。例如:
operator.itemgetter(1,3,5)
是相同的:
lambda s: (s[1], s[3], s[5])
在某些情况下有好处,这是一个很好的例子。
>>> data = [('a',3),('b',2),('c',1)]
>>> from operator import itemgetter
>>> sorted(data, key=itemgetter(1))
[('c', 1), ('b', 2), ('a', 3)]
这种使用itemgetter
非常棒,因为它使一切变得清晰,同时由于所有操作都保留在C
一边,速度也更快。
>>> sorted(data, key=lambda x:x[1])
[('c', 1), ('b', 2), ('a', 3)]
使用 alambda
不是很清楚,它也较慢,lambda
除非必须,否则最好不要使用。例如。列表推导式优于map
与 a 一起使用lambda
。
表现。它可以产生很大的不同。在适当的情况下,您可以使用 itemgetter 在 C 级别完成大量工作。
我认为更清晰的主张实际上取决于您最常使用的内容,并且非常主观
在or的key
参数中使用 this 时,考虑到 say和之间的选择,前者通常在两种情况下都快得多:sorted()
min()
operator.itemgetter(1)
lambda x: x[1]
使用sorted()
比较函数定义如下:
import operator
def sort_key_itemgetter(items, key=1):
return sorted(items, key=operator.itemgetter(key))
def sort_key_lambda(items, key=1):
return sorted(items, key=lambda x: x[key])
结果:sort_key_itemgetter()
快了 ~10% 到 ~15%。
(这里全面分析)
使用min()
比较函数定义如下:
import operator
def min_key_itemgetter(items, key=1):
return min(items, key=operator.itemgetter(key))
def min_key_lambda(items, key=1):
return min(items, key=lambda x: x[key])
结果:min_key_itemgetter()
快了 ~20% 到 ~60%。
(这里全面分析)
正如提到的性能,我已经比较了这两种方法operator.itemgetter
,lambda
并且对于一个小列表,结果证明它operator.itemgetter
优于 lambda 10%
。我个人喜欢这种itemgetter
方法,因为我主要在排序过程中使用它,它对我来说就像一个关键字。
import operator
import timeit
x = [[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]]
def sortOperator():
x.sort(key=operator.itemgetter(1, 2))
def sortLambda():
x.sort(key=lambda x:(x[1], x[2]))
if __name__ == "__main__":
print(timeit.timeit(stmt="sortOperator()", setup="from __main__ import sortOperator", number=10**7))
print(timeit.timeit(stmt="sortLambda()", setup="from __main__ import sortLambda", number=10**7))
>>Tuple: 9.79s, Single: 8.835s
>>Tuple: 11.12s, Single: 9.26s
撇开性能和代码风格不谈,itemgetter
是可以选择的,而lambda
不是。如果函数需要保存或在进程之间传递(通常作为较大对象的一部分),这一点很重要。在以下示例中,替换itemgetter
为lambda
将导致PicklingError
.
from operator import itemgetter
def sort_by_key(sequence, key):
return sorted(sequence, key=key)
if __name__ == "__main__":
from multiprocessing import Pool
items = [([(1,2),(4,1)], itemgetter(1)),
([(5,3),(2,7)], itemgetter(0))]
with Pool(5) as p:
result = p.starmap(sort_by_key, items)
print(result)
一些程序员理解并使用 lambdas,但也有一些程序员可能没有学过计算机科学并且不清楚这个概念。对于那些程序员itemgetter()
可以让你的意图更清晰。(我不写 lambda,任何时候我在代码中看到一个,我都需要一些额外的时间来处理正在发生的事情并理解代码)。
如果您正在为其他计算机科学专业人士编写代码,请继续使用 lambda,如果他们更舒服的话。但是,如果您正在为更广泛的受众编写代码。我建议使用itemgetter()
.