42

这里有一个比较笼统的问题:python中应该在什么情况下使用内置模块?operator

最佳答案声称operator.itemgetter(x)比大概比“更整洁” lambda a: a[x]。我觉得恰恰相反。

还有其他好处吗,比如性能?

4

7 回答 7

27

除非您的代码处于紧密的内部循环中,否则您不应该担心性能,这实际上是一个性能问题。相反,请使用最能表达您意图的代码。有些人喜欢 lambdas,有些人喜欢 itemgetter。有时这只是口味问题。

itemgetter更强大,例如,如果您需要一次获取多个元素。例如:

operator.itemgetter(1,3,5)

是相同的:

lambda s: (s[1], s[3], s[5])
于 2012-07-02T02:27:27.843 回答
17

在某些情况下有好处,这是一个很好的例子。

>>> 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

于 2012-07-02T02:30:16.693 回答
15

表现。它可以产生很大的不同。在适当的情况下,您可以使用 itemgetter 在 C 级别完成大量工作。

我认为更清晰的主张实际上取决于您最常使用的内容,并且非常主观

于 2012-07-02T02:30:11.033 回答
9

在or的key参数中使用 this 时,考虑到 say和之间的选择,前者通常在两种情况下都快得多:sorted()min()operator.itemgetter(1)lambda x: x[1]


使用sorted()

BM

比较函数定义如下:

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

(这里全面分析)

于 2019-09-30T15:35:18.473 回答
8

正如提到的性能,我已经比较了这两种方法operator.itemgetterlambda并且对于一个小列表,结果证明它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

在 Python 3.6 上运行

于 2018-01-22T17:40:55.400 回答
7

撇开性能和代码风格不谈,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)
于 2017-07-01T10:52:17.050 回答
5

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

如果您正在为其他计算机科学专业人士编写代码,请继续使用 lambda,如果他们更舒服的话。但是,如果您正在为更广泛的受众编写代码。我建议使用itemgetter().

于 2012-07-02T04:16:10.320 回答