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
Verzeichnistiefe ermitteln
-
- User
- Beiträge: 35
- Registriert: Samstag 12. Juli 2014, 01:59
Hallo Sirius3,
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
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.Sirius3 hat geschrieben:@Holger Chapman: was hast Du denn schon versucht? `os.walk` ist Dein Freund.
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)
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
-
- User
- Beiträge: 35
- Registriert: Samstag 12. Juli 2014, 01:59
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):__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 [...]
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)
Holger
-
- User
- Beiträge: 35
- Registriert: Samstag 12. Juli 2014, 01:59
Stimmt, danke für den Hinweis. (Und ein hart kodiertes '/' ist sowieso doof, wenn überhaupt hätte ich besser os.sep verwendet.)__deets__ hat geschrieben:Bitte os.path.join verwenden statt strings zusammen+zu+plussen. Aber schön das es klappt.
@__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)
-
- User
- Beiträge: 35
- Registriert: Samstag 12. Juli 2014, 01:59
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".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)
Danke!