Hallo Sirius3,
vielen Dank, Dein Vorschlag hat den Code noch ein ganzes Stück verbessert.
Was ich nicht verstanden habe: Ist es von Vorteil, die Funktion "is_subdirectory" zu benutzen? Wäre es von Nachteil, an Stelle von
Code: Alles auswählen
def is_subdirectory(parent, path):
return path.startswith(parent + os.sep)
if not result or not is_subdirectory(result[-1], path):
direkt die Bedingung
Code: Alles auswählen
if not result or not path.startswith(result[-1] + os.sep):
zu benutzen und die Funktion "is_subdirectory" wegzulassen? - Das erscheint mir übersichtlicher, als eine Funktion zu definieren, die nur an einer Stelle verwendet wird.
Und was ich anders machen möchte: Aus Deinem
Code: Alles auswählen
paths = sorted(os.path.realpath(os.path.normpath(path)) for path in paths)
möchte ich
Code: Alles auswählen
paths = sorted(os.path.abspath(path) for path in paths)
machen, weil symbolische Links in meinem Anwendungsfall nicht aufgelöst werden sollen.
Außerdem verwende ich bei den Variablenbezeichnungen lieber "file" als "dir" oder "path", weil der Code unabhängig davon funktionieren sollte, ob die Liste Dateien, Verzeichnisse oder Symlinks (oder eine Kombination davon) enthält.
(Wie nennt man eigentlich ein Element, das in einem Verzeichnis eines Dateisystems gelistet wird, wenn man noch nicht weiß, was genau es ist ("echte" Datei, Unterverzeichnis, Symlink, ...)? - "fso" (file system object)? "directory_entry"? Oder einfach nur "file" (gemäß dem Unix-Prinzip "Everything is a file")? - Ich habe mich für letzteres entschieden.)
Jedenfalls: So sieht mein kleines Programm jetzt aus:
Code: Alles auswählen
#!/usr/bin/env python2
import os
def simplify_file_list(file_list):
# - remove elements contained in higher-level directories, if element + dir are in file_list
# - convert relative file names to absolute file names (don't follow symlinks)
# - sort elements alphabetically
file_list = sorted(os.path.abspath(file_name) for file_name in file_list)
simplified_file_list = []
for file_name in file_list:
if not simplified_file_list or not file_name.startswith(simplified_file_list[-1] + os.sep):
simplified_file_list.append(file_name)
return simplified_file_list
# main
file_list = ['/d3/foo2', '/d1/sd1', '/d1', '/d1/sd1/file1', '/d2', '/d3/foo']
print 'before: ' + str(file_list)
file_list = simplify_file_list(file_list)
print ' after: ' + str(file_list)
Wie gesagt, vielen Dank für Deine Hilfe! - Aus nicht funktionierendem Code ist erst funktionierender Code und dann schlanker und übersichtlicher funktionierender Code geworden. - Du hast mir sehr geholfen!
Viele Grüße
Holger