2012-07-12 20 views
6

Ho una lista di tuple:Ordinamento complesso con più parametri?

li = [('fink', 3), ('flip', 3), ('flock', 4), ('foo', 12), ('foot', 20), ('football', 20), ('futz', 10), ('flip', 3), ('flank', 3), ('flop', 3)] 

Come posso ordinare l'elenco per numero di discesa e poi in ordine alfabetico decrescente? I risultati sarebbero:

('foot', 20) 
('football', 20) 
('foo', 12) 
('futz', 10) 
('flock', 4) 
('fink', 3) 
('flip', 3) 
('flake', 3) 
('flop', 3) 

from operator import itemgetter 

sorted_li = sorted(li, key=itemgetter(1,0), reverse=True) 

Mentre i tipi di codice di cui sopra per numero decrescente in modo corretto, le parole non sono in ordine alfabetico.

+0

possibile duplicato di [Criteri di ordinamento avanzati per un elenco di tuple annidate] (http://stackoverflow.com/questions/3831449/advanced-sorting-criteria-for-a-list-of-nested-tuples) – eumiro

risposta

9

Questo è troppo complicato per un singolo itemgetter. Utilizzare lambda invece:

sorted_li = sorted(li, key=lambda x: (-x[1], x[0])) 

Si tratta di circa la stessa velocità di due tipi consecutivi utilizzando itemgetter, ma è meno codice e, probabilmente, più leggibile.

+0

Questo funziona perché sei in grado di utilizzare il fatto che un elemento di ordinamento è un numero. E se entrambi fossero degli archi? –

+1

@JonClements Userebbe la tua soluzione :) – jamylak

6

come una sorta di Python è stabile, è più facile per ordinare due volte:

sorted_li = sorted(li, key=itemgetter(1), reverse=True) 
sorted_li.sort(key=itemgetter(0))