Seite 1 von 1

Verzeichnisinhalt nach Art und Name sortieren

Verfasst: Montag 7. Januar 2008, 14:25
von midan23
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 ?

Verfasst: Montag 7. Januar 2008, 14:49
von BlackJack
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

Verfasst: Montag 7. Januar 2008, 15:07
von midan23
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 ?

Verfasst: Montag 7. Januar 2008, 15:48
von BlackJack
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.

Verfasst: Montag 7. Januar 2008, 15:56
von midan23
Raffiniert ...

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

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