Seite 1 von 1

Nur die höchsten Elemente einer Verzeichnisstruktur erhalten

Verfasst: Sonntag 17. Juli 2011, 15:24
von Gremlin
Hallo, ich bin mal wieder auf der Suche nach einer Funktion. Bin leider selbst nicht fündig geworden, glaube aber trotzdem noch dass es sowas ähnliches geben müsste. Bin garantiert nicht der erste der sowas braucht. Bevor ich mir also nen "Kopf" mache und sie selbst erstelle... fragen kostet ja nichts.

Ich hätte gerne folgendes:

Code: Alles auswählen

>>> filter_highest([r'a\b\c', r'a\b', r'b\c\d', 'b', r'c\e'])
['a\\b', 'b', 'c\\e']
Gibts da was ähnliches? Standardlib? Snippet? Oder hat jemand ein "Stichwort" mit dem Google u. Co etwas passendes finden könnte?

Re: Nur die höchsten Elemente einer Verzeichnisstruktur erha

Verfasst: Sonntag 17. Juli 2011, 17:09
von BlackJack
@Gremlin: Also es sieht so aus, als wenn Du die Pfade erst nach dem ersten/obersten Element gruppieren möchtest und danach den „longest common prefix” in jeder Gruppe suchst.

Re: Nur die höchsten Elemente einer Verzeichnisstruktur erha

Verfasst: Sonntag 17. Juli 2011, 17:48
von /me
BlackJack hat geschrieben:@Gremlin: Also es sieht so aus, als wenn Du die Pfade erst nach dem ersten/obersten Element gruppieren möchtest und danach den „longest common prefix” in jeder Gruppe suchst.
Für zweiteres kann man dann os.path.commonprefix einsetzen

Re: Nur die höchsten Elemente einer Verzeichnisstruktur erha

Verfasst: Sonntag 17. Juli 2011, 19:17
von Gremlin
Danke BlackJack. Ist immer schöner zu wissen wovon man redet. :mrgreen:

Allerdings ist mir nach einiger Zeit doch eine Idee gekommen wie ich das relativ simpel lösen könnte. Gefällt mir auch von der Geschwindigkeit her recht gut. Nur sollte man nicht absolute und relative Pfade vermischen. :roll:

os.path.commonprefix hab ich auch mal probiert, aber auch da muss ich erst (wie erwähnt) die Pfade im voraus gruppieren, somit hat das ja auch keinen besonderen Vorteil gegenüber meinem Werk, oder?

Code: Alles auswählen

import os
import timeit


def filter_root_directories(dirs):
    filtered_dirs = []
    while dirs:
        path = dirs.pop(0)
        search_path = path
        if not search_path.endswith(os.sep):
            search_path = ''.join((search_path, os.sep))
        add = True
        for cmp_path in dirs[:]:
            if cmp_path.startswith(search_path):
                dirs.remove(cmp_path)
            else:
                if not cmp_path.endswith(os.sep):
                    cmp_path = ''.join((cmp_path, os.sep))
                if search_path.startswith(cmp_path):
                    add = False
                    break
        if add:
            filtered_dirs.append(path)
    return filtered_dirs


paths = ['eins\\zwei\\drei\\vier', 'eins\\drei\\zwei', 'zwei',
         'zwei\\drei', 'eins\\drei', 'eins\\zwei\\drei', 'sieben']

print filter_root_directories(paths[:])
print timeit.timeit('filter_root_directories(paths[:])',
                    'from __main__ import filter_root_directories, paths',
                    number=10)

Re: Nur die höchsten Elemente einer Verzeichnisstruktur erha

Verfasst: Sonntag 17. Juli 2011, 19:47
von BlackJack
@Gremlin: Es wäre wahrscheinlich weniger kryptisch und die Laufzeit sieht bei Dir auch nicht gerade schön aus. Das ist ja mindestens quadratisch.

Edit:

Code: Alles auswählen

import os
from itertools import groupby


def filter_root_directories(paths):
    
    def get_first_path_element(path):
        return path.split(os.path.sep, 1)[0]
    
    return [
        os.path.commonprefix(list(path_iter))
        for _, path_iter in groupby(sorted(paths), get_first_path_element)
    ]