operator.itemgetter or lambda

前端 未结 3 1673
情歌与酒
情歌与酒 2020-11-27 20:14

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

相关标签:
3条回答
  • 2020-11-27 20:32

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

    0 讨论(0)
  • 2020-11-27 20:38

    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
    
    0 讨论(0)
  • 2020-11-27 20:54

    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.

    0 讨论(0)
提交回复
热议问题