I was curious if there was any indication of which of operator.itemgetter(0)
or lambda x:x[0]
is better to use, specifically in sorted()
as the key
keyword argument as that's the use that springs to mind first. Are there any known performance differences? Are there any PEP related preferences or guidance on the matter?

- 21,038
- 13
- 59
- 90
-
1I would advise to use `operator.itemgetter(0)` – oleg Jun 21 '13 at 20:19
-
even over the standard readability? isn't this sort of performance-based decision making premature optimization? – hexparrot Jun 21 '13 at 20:21
-
1@hexparrot it's such a small code difference, and I don't think readability is better one way or the other. I'm just wondering for the sake of integrating whichever is "better" into my regular lexicon. – Endophage Jun 21 '13 at 20:23
-
1Possible duplicate of [Why should I use operator.itemgetter(x) instead of \[x\]?](http://stackoverflow.com/questions/11287207/why-should-i-use-operator-itemgetterx-instead-of-x) – Chris_Rands Jan 11 '17 at 09:13
3 Answers
The performance of itemgetter is slightly better:
>>> f1 = lambda: sorted(w, key=lambda x: x[1])
>>> f2 = lambda: sorted(w, key=itemgetter(1))
>>> timeit(f1)
21.33667682500527
>>> timeit(f2)
16.99106214600033

- 8,530
- 2
- 55
- 53

- 7,985
- 7
- 30
- 36
-
3But here what is being measured is the creation of the lambda functions. To measure the sorting itself the `timeit` calls should be `timeit(f1())` and `timeit(f2())`. Or am I missing something here? – dojuba Jul 11 '17 at 08:18
-
2
-
Leaving aside the speed issue, which is often based on where you make the itemgetter or lambda function, I personally find that itemgetter
is really nice for getting multiple items at once: for example, itemgetter(0, 4, 3, 9, 19, 20)
will create a function that returns a tuple of the items at the specified indices of the listlike object passed to it. To do that with a lambda, you'd need lambda x:x[0], x[4], x[3], x[9], x[19], x[20]
, which is a lot clunkier. (And then some packages such as numpy
have advanced indexing, which works a lot like itemgetter()
except built in to normal bracket notation.)
-
1+1 excellent point about multiple entries, certainly itemgetter is the winner there. – Endophage Jun 21 '13 at 20:25
According to my benchmark on a list of 1000 tuples, using itemgetter
is almost twice as quick as the plain lambda
method. The following is my code:
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)
I have also tested the performance (run time in µs) of this two method for various list size.
+-----------+--------+------------+
| List size | lambda | itemgetter |
+-----------+--------+------------+
| 100 | 8.19 | 5.09 |
+-----------+--------+------------+
| 1000 | 81.4 | 47 |
+-----------+--------+------------+
| 10000 | 855 | 498 |
+-----------+--------+------------+
| 100000 | 14600 | 10100 |
+-----------+--------+------------+
| 1000000 | 172000 | 131000 |
+-----------+--------+------------+
(The code producing the above image can be found here)
Combined with the conciseness to select multiple elements from a list, itemgetter
is clearly the winner to use in sort method.

- 24,001
- 18
- 134
- 273