Seite 1 von 1

Verzeichnistiefe ermitteln

Verfasst: Donnerstag 22. Februar 2018, 23:48
von Holger Chapman
Hallo,

ich möchte gern die Tiefe eines Verzeichnisses ermitteln. Das heißt: Ich will wissen, wie viele Unterverzeichnis-Ebenen ein Verzeichnis hat. - Könnt ihr mir da helfen?

Zum besseren Verständnis:
Ein Verzeichnis ohne Unterverzeichnis soll die Tiefe 0 haben.
Ein Verzeichnis mit mindestens einem Unterverzeichnis (aber ohne ein Unterunterverzeichnis) soll die Tiefe 1 haben.
Ein Verzeichnis mit mindestens einem Unterunterverzeichnis (aber ohne ein Unterunterunterverzeichnis) soll die Tiefe 2 haben.
Ein Verzeichnis mit mindestens einem Unterunterunterverzeichnis (aber ohne ein Unterunterunterunterverzeichnis) soll die Tiefe 3 haben.
Usw.

Es läuft vermutlich darauf hinaus, dass ich beim rekursiven Durchlaufen einer Verzeichnisstruktur zählen will, welche die maximal durchlaufene Rekursionsstufe ist.

Hat jemand von euch eine Idee, wie sich das umsetzen lässt?

Vielen Dank!


Holger

Re: Verzeichnistiefe ermitteln

Verfasst: Freitag 23. Februar 2018, 00:05
von Sirius3
@Holger Chapman: was hast Du denn schon versucht? `os.walk` ist Dein Freund.

Re: Verzeichnistiefe ermitteln

Verfasst: Samstag 24. Februar 2018, 08:58
von Holger Chapman
Hallo Sirius3,
Sirius3 hat geschrieben:@Holger Chapman: was hast Du denn schon versucht? `os.walk` ist Dein Freund.
Ich habe das Folgende probiert, aber das liefert einen viel zu hohen Wert zurück. - Und irgendwie habe ich das Gefühl, ich mache es viel komplizierter als nötig.
Der Fehler ist wohl, dass der Wert für "depth" nicht reduziert wird, wenn der Weg in einen Unterverzeichniszweig sich als unnötig erwiesen hat, weil darin nicht das "tiefste" Unter-Unterverzeichnis war. Aber ich habe noch nicht die passende Stelle/Bedingung gefunden, um das abzufragen.

Vielleicht kann mir hier jemand helfen?

Danke und schönen Gruß


Holger

Code: Alles auswählen

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

import os

def get_subdirs(dir, depth):
    '''
    returns a) list of subdirs + b) new maximum depth for ...
    ... a) given dir ('dir') and b) current directory depth ('depth')
    '''
    # returns list of subdirs
    print "start: get_subdirs('{}', {})".format(dir, depth)
    subdirs=[]
    for diritself, subdirs, files in os.walk(dir):
        if not subdirs==[]:
            # there's at least one subdir
            depth = depth + 1
            for subdir in subdirs:
                get_subdirs(subdir, depth)
    return subdirs, depth

# main

testdir='test'
maxdepth = 0  # will be increased later on
subdirs, maxdepth = get_subdirs(testdir, maxdepth)
print "maximum subdir depth of '{}': {}".format(testdir, maxdepth)

Re: Verzeichnistiefe ermitteln

Verfasst: Samstag 24. Februar 2018, 10:36
von __deets__
Ich halte os.walk genau hier nicht für deinen Freund. Denn es nimmt genau den Aspekt aus der Logik, der für dein Problem der Lösungsansatz ist: Rekursion. Das Problem wird trivial wenn man sich eine eigene Traversal-Funktion schreibt die skizziert so aussieht:

Code: Alles auswählen

def dir_depth(path):
      subdirs = subdirs_of_dir(path)
      if not subdirs:
            return 0
      return max(dir_depth(sd) for sd in subdirs) + 1

Re: Verzeichnistiefe ermitteln

Verfasst: Samstag 24. Februar 2018, 15:37
von Holger Chapman
__deets__ hat geschrieben:Ich halte os.walk genau hier nicht für deinen Freund. Denn es nimmt genau den Aspekt aus der Logik, der für dein Problem der Lösungsansatz ist: Rekursion. Das Problem wird trivial wenn man sich eine eigene Traversal-Funktion schreibt die skizziert so aussieht [...]
Danke! - Folgendes scheint zu funktionieren (wobei ich mir noch Gedanken darüber machen muss, wie ich symbolische Links und Ordner mit fehlenden Zugriffsrechten behandeln will):

Code: Alles auswählen

#!/usr/bin/env python2

import os

def subdirs_of_dir(path):
    return [path + '/' + name for name in os.listdir(path)
        if os.path.isdir(os.path.join(path, name))]

def dir_depth(path):
    subdirs = subdirs_of_dir(path)
    if not subdirs:
        return 0
    return max(dir_depth(sd) for sd in subdirs) + 1

dirpath = '/home/holgerc/test'
print dir_depth(dirpath)
Schönen Gruß


Holger

Re: Verzeichnistiefe ermitteln

Verfasst: Samstag 24. Februar 2018, 16:11
von __deets__
Bitte os.path.join verwenden statt strings zusammen+zu+plussen. Aber schön das es klappt.

Re: Verzeichnistiefe ermitteln

Verfasst: Samstag 24. Februar 2018, 17:59
von Holger Chapman
__deets__ hat geschrieben:Bitte os.path.join verwenden statt strings zusammen+zu+plussen. Aber schön das es klappt.
Stimmt, danke für den Hinweis. (Und ein hart kodiertes '/' ist sowieso doof, wenn überhaupt hätte ich besser os.sep verwendet.)

Re: Verzeichnistiefe ermitteln

Verfasst: Samstag 24. Februar 2018, 20:59
von Sirius3
@__deets__: `os.walk` erledigt die Rekursion halt schon für einen:

Code: Alles auswählen

def dir_depth(path):
    return max(p.count(os.sep) for p, _, _ in os.walk(path)) - path.count(os.sep)

Re: Verzeichnistiefe ermitteln

Verfasst: Montag 26. Februar 2018, 22:22
von Holger Chapman
Sirius3 hat geschrieben:

Code: Alles auswählen

def dir_depth(path):
    return max(p.count(os.sep) for p, _, _ in os.walk(path)) - path.count(os.sep)
Wow, sehr schön und kurz. Das bestätigt meine anfängliche Vermutung: "irgendwie habe ich das Gefühl, ich mache es viel komplizierter als nötig".

Danke!