2012-05-22 12 views

Respuesta

390

Trate de usar la palabra clave key con sorted().

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda x: x[1]) 

key debería ser una función que identifica cómo recuperar el elemento comparables de su estructura de datos. En su caso, es el segundo elemento de la tupla, por lo que accedemos al [1].

Para la optimización, consulte la respuesta de jamylak utilizando itemgetter(1), que es esencialmente una versión más rápida de lambda x: x[1].

149
>>> from operator import itemgetter 
>>> data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)] 
>>> sorted(data,key=itemgetter(1)) 
[('abc', 121), ('abc', 148), ('abc', 221), ('abc', 231)] 

OMI utilizando itemgetter es más fácil de leer en este caso que la solución mediante @cheeken. Es también más rápido ya que casi todo el cálculo se realizará en el lado c (sin juego de palabras) en lugar de mediante el uso de lambda.

>python -m timeit -s "from operator import itemgetter; data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=itemgetter(1))" 
1000000 loops, best of 3: 1.22 usec per loop 

>python -m timeit -s "data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=lambda x: x[1])" 
1000000 loops, best of 3: 1.4 usec per loop 
+10

+1 Me acuerdo en que 'itemgetter()' es una solución mejor.Sin embargo, pensé que una expresión lambda aclararía cómo funciona 'key'. – cheeken

+0

+1 Sin embargo, cuando realicé la prueba de la velocidad, noté "ojo humano" que el que se suponía que era más rápido ... y que medía más rápido, en realidad era notablemente más lento. Me rasqué la cabeza en esto por un rato, luego tomé el módulo de tiempo de espera de python fuera de juego y solo usé el tiempo de Linux. es decir 'time \' python -c "el código" \ '' luego obtuve los resultados de 'ojo humano' que deletreas, así como los tiempos de reloj del sistema que eran más rápidos. Todavía no estoy seguro de por qué es esto, pero fue reproducible. Supongo que tiene algo que ver con la sobrecarga de la carga en el módulo, pero aún no acaba de hacerlo, por ahora. –

+1

@JeffSheffield: Observe que jamylak está haciendo la importación en el código de configuración (fuera del tiempo), no el código probado. Eso es perfectamente razonable, porque la mayoría de los programas necesitarán clasificar más de una vez, o deben ordenar colecciones mucho más grandes, pero solo realizarán la importación una vez. (Y para aquellos programas que solo necesitan hacer un tipo más bien pequeño ... bueno, estás hablando de una diferencia de menos de un microsegundo, ¿a quién le importa de algún modo?) – abarnert

13

De pitón wiki:

>>> from operator import itemgetter, attrgetter  
>>> sorted(student_tuples, key=itemgetter(2)) 
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]  
>>> sorted(student_objects, key=attrgetter('age')) 
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] 
+0

x = [[[5,3], 1.0345], [[5,6], 5.098], [[5,4], 4.89], [[5,1], 5.97]] Con una lista como esta es ¿Podemos ordenar utilizando itemgetter() con respecto a los elementos en x [0] [1]? – nidHi

31

Como neófito pitón, sólo quería mencionar que si los datos hicieron realidad este aspecto:

data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)] 

continuación sorted() haría ordenar automáticamente por el segundo elemento en la tupla, ya que los primeros elementos son todos idénticos.

26

Agregando a la respuesta de Cheeken, Así es como clasificas una lista de tuplas por el 2do artículo en orden descendente.

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)],key=lambda x: x[1], reverse=True) 
5

Para un método lambda-evitar, primero definir su propia función:

def MyFn(a): 
    return a[1] 

a continuación:

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=MyFn) 
+2

¿Cuáles son los beneficios de esto? – dromtrund

+4

Un beneficio sería tener una función definida que podría usar en cualquier lugar sin tener que poner 'lambda x: x [1]' en múltiples áreas de código. –

+0

Otra ventaja es que puede documentar/comentar mejor si se trata de una función separada. – uli42

2

Para Python 2.7+, esto funciona lo que hace que la respuesta aceptada ligeramente más legible:

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda (k, val): val) 
0

El hecho de que los valores de clasificación en el OP sean enteros no es relevante para la pregunta per se. En otras palabras, la respuesta aceptada funcionaría si el valor de clasificación fuera texto. Traigo esto también para señalar que la clasificación puede modificarse durante el orden (por ejemplo, para tener en cuenta mayúsculas y minúsculas).

>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: x[1]) 
[(148, 'ABC'), (221, 'DEF'), (121, 'abc'), (231, 'def')] 
>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: str.lower(x[1])) 
[(121, 'abc'), (148, 'ABC'), (231, 'def'), (221, 'DEF')] 
3

Para un tipo en el lugar, utilizar

foo = [(list of tuples)] 
foo.sort(key=lambda x:x[0]) #To sort by first element of the tuple 
+1

Aunque esta respuesta puede ser correcta, es mejor explicar por qué esta respuesta es correcta en lugar de solo proporcionar código. Además, esta es casi una respuesta exacta de una que ya existe y fue aceptada hace 5 años, por lo que realmente no agrega nada al sitio. Echa un vistazo a las preguntas más nuevas para ayudar a la gente. – JNYRanger

Cuestiones relacionadas