为什么我应该使用operator.itemgetter(x)而不是[x]?

the*_*man 34 python operators

这里有一个更普遍的问题:在什么情况下应该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)

  • 我非常肯定Ned意味着它比[]运算符更强大,这就是提问者所要求的.显然,它比lambda中的任意Python代码更强大是没有意义的. (11认同)
  • "itemgetter更强大"?这看起来倒退了; 我可以用lambda做很多事情,而我无法用itemgetter做.我想,它可以更紧凑. (8认同)
  • 通用性 != power,如果是这样,我们都会编写程序集。 (3认同)
  • 我认为正确的用语是具体的。特异性是好的,因为它是限制性的。 (2认同)

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.

  • 我个人认为lambdas在这些情况下更清楚.什么是"明确的"不是客观的主张.`itemgetter`和朋友只不过是特别命名的lambdas(概念上).我怀疑那些*已经对lambdas感到舒服的人(也许是因为他们做了大量的函数式编程)发现`lambda`更清晰(因为他们已经知道`lambda`和已经知道的`thing [index]`,所以lambda"只是说它意味着什么",而`itemgetter`需要记住一个额外的名字),而那些不习惯用lambdas思考的人更容易找到`itemgetter`. (16认同)

Joh*_*ooy 11

性能.它可以产生很大的不同.在适当的情况下,您可以使用itemgetter在C级别完成一堆内容.

我认为更清楚的主张实际上取决于你最常用的东西,而且非常主观


nor*_*ok2 8

当在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%。

(完整分析在这里


mon*_*kut 7

一些程序员理解并使用lambdas,但是有一群程序员可能没有接受计算机科学,也不清楚这个概念.对于那些程序员itemgetter()可以让你的意图更清晰.(我不写lambdas,任何时候我在代码中看到一个,它需要一点额外的时间来处理正在发生的事情并理解代码).

如果您对其他计算机科学专业人员的编码继续使用lambdas,如果他们更舒服.但是,如果您为更广泛的受众编码我建议使用itemgetter().


use*_*754 6

提到性能时,我对这两种方法进行了比较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)

在Python 3.6上运行


eag*_*ain 5

撇开性能和代码风格,itemgetter可以选择,但lambda不可以。如果功能需要保存或在过程之间传递(通常是作为较大对象的一部分),则这一点很重要。在以下示例中,替换itemgetterlambda将导致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)