2009-11-05 12 views
9

Ich habe this post gelesen und ist nicht für mich gelaufen.Sortiere eine mehrdimensionale Liste nach einer variablen Anzahl von Schlüsseln

Edit: die Funktionalität, die ich beschreiben habe, ist, genau wie die Sortierfunktion in Excel ... wenn das macht es noch klarer

Hier ist meine Situation, ich habe ein getabulatortrennte Textdokument. Es gibt ungefähr 125.000 Zeilen und 6 Spalten pro Zeile (Spalten sind durch ein Tab-Zeichen getrennt). Ich habe das Dokument in eine zweidimensionale Liste aufgeteilt.

Ich versuche, eine generische Funktion zu schreiben, um zweidimensionale Listen zu sortieren. Grundsätzlich hätte ich gerne eine Funktion, bei der ich die große Liste und den Schlüssel einer oder mehrerer Spalten übergeben kann, nach denen ich die große Liste sortieren möchte. Offensichtlich möchte ich, dass der erste übergebene Schlüssel der primäre Sortierpunkt ist, dann der zweite Schlüssel usw.

Noch konfus?

Hier ist ein Beispiel, was ich tun möchte.

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 

sagen, dass ich diese Liste, um meine magische Funktion übergeben, etwa so:

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 

und ...

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 

Irgendwelche Hinweise? Dies wird durch Spalten 2 und 3

Antwort

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

Das ist fabelhaft. Ich hatte noch nie von itemgetter (oder attrgetter, was ich jetzt auch sehe) gehört. –

+2

Das ist Guido's Zeitmaschine für Sie. http://catb.org/jargon/html/G/Guido.html –

+0

Dies ist genau das, was ich suche. Danke vielmals! –

8

sortieren:

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

Achten Sie darauf, um die Zahlen zu Ints konvertiert haben, sonst werden sie alphabetisch sortieren, anstatt numerisch

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

oder

# 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

Die Schlüsselidee hier (Wortspiel beabsichtigt) ist, eine Schlüsselfunktion zu verwenden, die ein Tupel zurückgibt. Unten ist die Tastenfunktion lambda x: (x[idx] for idx in args) x ist gleich einem Element der aList gesetzt - das heißt, eine Reihe von Daten. Es gibt ein Tupel von Werten zurück, nicht nur einen Wert. Die Methode sort() sortiert nach dem ersten Element der Liste, bricht dann die Verknüpfung mit der zweiten usw. ab. Siehe 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

Die Zahlen müssen in Ints umgewandelt werden –

+0

Guter Punkt, Gnibbler. Fest. – unutbu

Verwandte Themen