2010-07-09 18 views
37

¿Cómo puedo ordenar una lista por una clave descrita por una función arbitraria? Por ejemplo, si tengo:Ordenando por lambda arbitraria

mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 

me gustaría ordenar "mylist" por el segundo elemento de cada miembro, por ejemplo,

sort(mylist, key=lambda x: x[1]) 

¿cómo puedo hacer esto?

+0

¿Cuál fue el problema cuando probó el código que usted proporciona? – tzot

Respuesta

37

que básicamente tienen ya:

>>> mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 
>>> mylist.sort(key=lambda x: x[1]) 
>>> print mylist 

da:

[['bar', 0, 'b'], ['quux', 1, 'a']] 

Eso ordenará mi lista en su lugar.

[este para ha sido editado gracias a @ Daniel's correction.] sorted devolverá una nueva lista que se ordena en lugar de realmente cambiar la entrada, como se describe en http://wiki.python.org/moin/HowTo/Sorting/.

+0

Es bueno saber la distinción, gracias. – user248237dfsf

4

La respuesta es utilizar "ordenados", es decir

sorted(mylist, key=lambda x: x[1]) 
+0

Tenía los parámetros al revés. Parece inconsistente que, p. map/filter/reduce toma el primer parámetro lambda y lista el segundo parámetro pero ordena el reverso. – javadba

7

Usted tiene dos opciones, muy cerca de lo que usted describe, en realidad:

mylist.sort(key=lambda x: x[1]) # In place sort 
new_list = sorted(mylist, key=lambda x: x[1]) 
9

Esta es una necesidad tan común que el apoyo que se ha añadido a la biblioteca estándar, en forma de operator.itemgetter:

from operator import itemgetter 
mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 
mylist.sort(key=itemgetter(1)) # or sorted(mylist, key=...) 
4

Ordenar y itemgetter es el más rápido.

>>> import operator 
>>> import timeit 

>>> mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 
>>> t1 = timeit.Timer(lambda: mylist.sort(key=lambda x: x[1])) 
>>> t1.timeit() 
1.6330803055632404 

>>> t2 = timeit.Timer(lambda: mylist.sort(key=operator.itemgetter(1))) 
>>> t2.timeit() 
1.3985503043467773 

>>> t3 = timeit.Timer(lambda: sorted(mylist, key=operator.itemgetter(1))) 
>>> t3.timeit() 
2.6329514733833292 

>>> t4 = timeit.Timer(lambda: sorted(mylist, key=lambda x: x[1])) 
>>> t4.timeit() 
2.9197154810598533