Verzeichnisinhalt nach Art und Name sortieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
midan23
User
Beiträge: 119
Registriert: Sonntag 21. Mai 2006, 21:41
Wohnort: Müchen
Kontaktdaten:

Montag 7. Januar 2008, 14:25

Hallo zusammen.

Für ein kleines Projekt brauche ich eine Funktion, die mir den Inhalt eines Ordners als Liste zurück gibt.
Jedes Element der Liste ist ein Tupel. Das erste Element des Tupels ist immer der Name. Das zweite Tupelelement ist bei Ordnern immer "DIR", ansonsten die Dateigrösse.

Das wäre ja noch kein all zu grosses Problem ... Leider hätte ich diese Liste gerne sortiert:
Zuerst alle Ordner alphabetisch sortiert ohne Unterscheidung zwischen Gross- und Kleinbuchstaben
Danach alle Dateien, auf die gleiche Weise sortiert.

Hier mal mein erster Versuch:

Code: Alles auswählen

def get_dir_content(dirname):
    dir_list = []
    file_list = []
    for name in [".."] + os.listdir(dirname):
        path = os.path.join(dirname, name)
        if os.path.isdir(path):
            dir_list.append((name, "DIR"))
        else:
            file_list.append((name, str(os.stat(path)[6])))
    sort_func = lambda x,y: cmp(x[0].lower(), y[0].lower())
    dir_list.sort(sort_func)
    file_list.sort(sort_func)
    return dir_list + file_list
Ich weiss nicht wie ihr darüber denkt, aber mir kommt das etwas kompliziert vor ...
Kann man das auch etwas einfacher machen ?
BlackJack

Montag 7. Januar 2008, 14:49

Ich hätt's so umgesetzt:

Code: Alles auswählen

def get_dir_content(dirname):
    def size_or_dir(name):
        path = os.path.join(dirname, name)
        if os.path.isdir(path):
            size = 'DIR'
        else:
            size = str(os.path.getsize(path))
        return (name, size)
    
    result = map(size_or_dir, ['..'] + os.listdir(dirname))
    result.sort(key=lambda (name, size): (size != 'DIR', name.lower()))
    return result
midan23
User
Beiträge: 119
Registriert: Sonntag 21. Mai 2006, 21:41
Wohnort: Müchen
Kontaktdaten:

Montag 7. Januar 2008, 15:07

Ich hatte auch mit der erweiterten kompletten Liste angefangen ... aber die Sortierung danach hatte ich nicht hinbekommen ...

Sah übrigends so aus:

Code: Alles auswählen

nameinfo = lambda path: "DIR" if os.path.isdir(path) else str(os.path.getsize(path))
result = [(name, nameinfo(os.path.join(dirname, name))) for name in [".."] + os.listdir(dirname)]
@BlackJack: Wenn ich mir deine Sortierfunktion so anschaue, wundert es mich nicht, das ich das nicht hinbekommen habe ... Wie funktioniert sie ?
BlackJack

Montag 7. Januar 2008, 15:48

Die `key`-Funktion wird auf alle Elemente einmal angewendet und gibt das zurück was dann letztendlich ganz normal sortiert wird. Dabei werden die dazugehörigen Original-Objekte mit sortiert.

Für jeden Eintrag wird also ein Tupel aus einem Wahrheitswert und dem Namen in Kleinbuchstaben gebildet. Dabei wird ausgenutzt, dass `False` kleiner als `True` ist, und somit die Verzeichnisse alle "kleiner" sind als Dateien.
midan23
User
Beiträge: 119
Registriert: Sonntag 21. Mai 2006, 21:41
Wohnort: Müchen
Kontaktdaten:

Montag 7. Januar 2008, 15:56

Raffiniert ...

Und Danke für deine Unterstützung ... Funktioniert tadellos ...

(Vielleicht wird mein NC-Klon ja doch noch mal fertig ...)
Antworten