operator.itemgetter o lambda

Tenía curiosidad si había alguna indicación de cuál de operator.itemgetter(0) o lambda x:x[0] es mejor usar, específicamente en sorted() como el argumento key palabra key ya que ese es el uso que viene a la mente primero. ¿Hay diferencias de rendimiento conocidas? ¿Hay alguna preferencia u orientación relacionada con el PEP al respecto?

El rendimiento de itemgetter es ligeramente mejor:

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

Dejando a un lado el problema de la velocidad, que a menudo se basa en el lugar en el que realizas la función itemgetter o lambda, personalmente encuentro que el itemgetter es realmente bueno para obtener varios elementos a la vez: por ejemplo, itemgetter(0, 4, 3, 9, 19, 20) creará una función que devuelve una tupla de los elementos en los índices especificados del objeto listlike pasado a él. Para hacer eso con un lambda, necesitarías lambda x:x[0], x[4], x[3], x[9], x[19], x[20] , lo cual es mucho más complicado. (Y luego algunos paquetes como numpy tienen indexación avanzada, que funciona de forma muy parecida a itemgetter() excepto que está incorporado a la notación de corchete normal).

De acuerdo con mi punto de referencia en una lista de 1000 tuplas, el uso de itemgetter es casi el doble de rápido que el método lambda simple. El siguiente es mi código:

 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) 

También he probado el rendimiento (tiempo de ejecución en µs) de estos dos métodos para varios tamaños de lista.

 +-----------+--------+------------+ | List size | lambda | itemgetter | +-----------+--------+------------+ | 100 | 8.19 | 5.09 | +-----------+--------+------------+ | 1000 | 81.4 | 47 | +-----------+--------+------------+ | 10000 | 855 | 498 | +-----------+--------+------------+ | 100000 | 14600 | 10100 | +-----------+--------+------------+ | 1000000 | 172000 | 131000 | +-----------+--------+------------+ 

introduzca la descripción de la imagen aquí

(El código que produce la imagen anterior se puede encontrar aquí )

Combinado con la concisión para seleccionar múltiples elementos de una lista, itemgetter es claramente el ganador para usar en el método de clasificación.