operator.itemgetter或lambda

End*_*age 26 python python-2.7 python-3.x

我很好奇是否有任何关于哪个operator.itemgetter(0)或哪个lambda x:x[0]更好用的指示,特别是sorted()作为key关键字参数,因为这是首先考虑的用途.有任何已知的性能差异吗?是否有任何与PEP相关的偏好或指导?

mic*_*yer 35

itemgetter的性能稍好一些:

>>> f1 = lambda: sorted(w, key=lambda x: x[1])
>>> f2 = lambda: sorted(w, key=itemgetter(1))
>>> timeit(f1)
21.33667682500527
>>> timeit(f2)
16.99106214600033
Run Code Online (Sandbox Code Playgroud)

  • 但这里测量的是 lambda 函数的创建。为了衡量排序本身,`timeit` 调用应该是 `timeit(f1())` 和 `timeit(f2())`。还是我在这里遗漏了什么? (2认同)
  • @dojuba `timeit.timeit` 如果它不是字符串,则调用它的参数。 (2认同)

JAB*_*JAB 14

暂且不谈速度问题,这通常基于你创建itemgetter或lambda函数的位置,我个人觉得这itemgetter对于同时获取多个项目非常好:例如,itemgetter(0, 4, 3, 9, 19, 20)将创建一个返回项目元组的函数.传递给它的listlike对象的指定索引.要做一个lambda,你需要lambda x:x[0], x[4], x[3], x[9], x[19], x[20],这是很多笨蛋.(然后有一些软件包,例如numpy具有高级索引,itemgetter()除了内置到普通括号表示法之外,其工作方式非常类似.)


jdh*_*hao 10

根据我对 1000 个元组列表的基准测试,使用itemgetter的速度几乎是普通lambda方法的两倍。以下是我的代码:

In [1]: a = list(range(1000))

In [2]: b = list(range(1000))

In [3]: import random

In [4]: random.shuffle(a)

In [5]: random.shuffle(b)

In [6]: c = list(zip(a, b))

In [7]: %timeit c.sort(key=lambda x: x[1])
81.4 µs ± 433 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [8]: random.shuffle(c)

In [9]: from operator import itemgetter

In [10]: %timeit c.sort(key=itemgetter(1))
47 µs ± 202 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Run Code Online (Sandbox Code Playgroud)

我还针对不同的列表大小测试了这两种方法的性能(运行时间以微秒为单位)。

+-----------+--------+------------+
| List size | lambda | itemgetter |
+-----------+--------+------------+
| 100       | 8.19   | 5.09       |
+-----------+--------+------------+
| 1000      | 81.4   | 47         |
+-----------+--------+------------+
| 10000     | 855    | 498        |
+-----------+--------+------------+
| 100000    | 14600  | 10100      |
+-----------+--------+------------+
| 1000000   | 172000 | 131000     |
+-----------+--------+------------+
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

(生成上图的代码可以在这里找到)

结合从列表中选择多个元素的简洁性,itemgetter显然是排序方法的赢家。