2009-11-05 12 views
9

Ho letto this post e non ha finito per funzionare per me.Ordinare una lista multidimensionale per un numero variabile di chiavi

Edit: la funzionalità che sto descrivendo è proprio come la funzione di ordinamento in Excel ... se questo lo rende più chiaro

Ecco la mia situazione, ho un documento di testo delimitato da tabulazioni. Ci sono circa 125.000 righe e 6 colonne per riga (le colonne sono separate da un carattere di tabulazione). Ho diviso il documento in un elenco di due dimensioni.

Sto tentando di scrivere una funzione generica per ordinare elenchi bidimensionali. Fondamentalmente mi piacerebbe avere una funzione in cui posso passare la lista grande, e la chiave di una o più colonne vorrei ordinare la grande lista per. Ovviamente, vorrei che la prima chiave passasse per essere il punto di ordinamento primario, poi la seconda chiave, ecc.

Ancora confuzzled?

Ecco un esempio di cosa mi piacerebbe fare.

Joel 18 Orange 1 
Anna 17 Blue 2 
Ryan 18 Green 3 
Luke 16 Blue 1 
Katy 13 Pink 5 
Tyler 22 Blue 6 
Bob  22 Blue 10 
Garrett 24 Red 7 
Ryan 18 Green 8 
Leland 18 Yellow 9 

dire che ho passato questa lista per la mia funzione magica, in questo modo:

sortByColumn(bigList, 0) 

Anna 17 Blue 2 
Bob  22 Blue 10 
Garrett 24 Red 7 
Joel 18 Orange 1 
Katy 13 Pink 5 
Leland 18 Yellow 9 
Luke 16 Blue 1 
Ryan 18 Green 3 
Ryan 18 Green 8 
Tyler 22 Blue 6 

e ...

sortByColumn(bigList, 2, 3) 

Luke 16 Blue 1 
Anna 17 Blue 2 
Tyler 22 Blue 6 
Bob  22 Blue 10 
Ryan 18 Green 3 
Ryan 18 Green 8 
Joel 18 Orange 1 
Katy 13 Pink 5 
Garrett 24 Red 7 
Leland 18 Yellow 9 

Degli indizi?

risposta

11
import operator: 
def sortByColumn(bigList, *args) 
    bigList.sort(key=operator.itemgetter(*args)) # sorts the list in place 
+0

È favoloso. Non avevo mai sentito parlare di itemgetter (o attrgetter, che ora vedo anche io). –

+2

Questa è la macchina del tempo di Guido per te. http://catb.org/jargon/html/G/Guido.html –

+0

Questo è esattamente quello che sto cercando. Molte grazie! –

8

Ciò ordinerà da colonne 2 e 3:

a.sort(key=operator.itemgetter(2,3)) 
1

Assicurarsi di aver convertito i numeri per interi, altrimenti si ordina alfabeticamente piuttosto che numerico

# Sort the list in place 
def sortByColumn(A,*args): 
    import operator 
    A.sort(key=operator.itemgetter(*args)) 
    return A 

o

# Leave the original list alone and return a new sorted one 
def sortByColumn(A,*args): 
    import opertator 
    return sorted(A,key=operator.itemgetter(*args)) 
2

L'idea chiave qui (gioco di parole) consiste nell'utilizzare una funzione chiave che restituisce una tupla. Di seguito, la funzione chiave è lambda x: (x[idx] for idx in args) x è impostata su uguale a un elemento di elenco, ovvero una riga di dati. Restituisce una tupla di valori, non solo un valore. Il metodo sort() ordina in base al primo elemento dell'elenco, quindi rompe i legami con il secondo e così via. Vedi http://wiki.python.org/moin/HowTo/Sorting#Sortingbykeys

#!/usr/bin/env python 
import csv 
def sortByColumn(aList,*args): 
    aList.sort(key=lambda x: (x[idx] for idx in args)) 
    return aList 

filename='file.txt' 
def convert_ints(astr): 
    try: 
     return int(astr) 
    except ValueError: 
     return astr  
biglist=[[convert_ints(elt) for elt in line] 
     for line in csv.reader(open(filename,'r'),delimiter='\t')] 

for row in sortByColumn(biglist,0): 
    print row 

for row in sortByColumn(biglist,2,3): 
    print row 
+1

I numeri devono essere convertiti in inti –

+0

Buon punto, gnibbler. Fisso. – unutbu

Problemi correlati