这里有一个更普遍的问题:在什么情况下应该operator在python中使用内置模块?
最高的回答声称operator.itemgetter(x)"整洁"比大概要好lambda a: a[x].我觉得情况恰恰相反.
还有其他好处,比如表现吗?
Ned*_*der 22
除非您的代码处于紧密的内循环中,否则您不应该担心性能,并且实际上是性能问题.相反,请使用最能表达您意图的代码.有些人喜欢lambdas,有些人喜欢itemgetter.有时它只是一个品味问题.
itemgetter例如,如果你需要一次获得许多元素,那就更强大了.例如:
operator.itemgetter(1,3,5)
Run Code Online (Sandbox Code Playgroud)
是相同的:
lambda s: (s[1], s[3], s[5])
Run Code Online (Sandbox Code Playgroud)
jam*_*lak 14
在某些情况下有好处,这是一个很好的例子.
>>> data = [('a',3),('b',2),('c',1)]
>>> from operator import itemgetter
>>> sorted(data, key=itemgetter(1))
[('c', 1), ('b', 2), ('a', 3)]
Run Code Online (Sandbox Code Playgroud)
这种使用itemgetter很棒,因为它可以使一切清晰,同时也可以更快,因为所有操作都保持在C一边.
>>> sorted(data, key=lambda x:x[1])
[('c', 1), ('b', 2), ('a', 3)]
Run Code Online (Sandbox Code Playgroud)
使用a lambda不是很清楚,它也较慢,lambda除非必须,否则最好不要使用.例如.列表推导优于使用mapa lambda.
当在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])
Run Code Online (Sandbox Code Playgroud)
结果: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])
Run Code Online (Sandbox Code Playgroud)
结果:min_key_itemgetter()速度提高了 ~20% 到 ~60%。
(完整分析在这里)
一些程序员理解并使用lambdas,但是有一群程序员可能没有接受计算机科学,也不清楚这个概念.对于那些程序员itemgetter()可以让你的意图更清晰.(我不写lambdas,任何时候我在代码中看到一个,它需要一点额外的时间来处理正在发生的事情并理解代码).
如果您对其他计算机科学专业人员的编码继续使用lambdas,如果他们更舒服.但是,如果您为更广泛的受众编码我建议使用itemgetter().
提到性能时,我对这两种方法进行了比较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
Run Code Online (Sandbox Code Playgroud)
撇开性能和代码风格,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)
Run Code Online (Sandbox Code Playgroud)