Seite 1 von 1
Verzeichnis liste ohne versteckte Verzeichnisse...
Verfasst: Montag 14. Juli 2008, 14:16
von jens
Stehe gerade auf den Schlauch... Ich möchte eine Liste aller Verzeichnisse und Unterverzeichnisse, aber ohne versteckte Verzeichnisse... Also alle Pfade die mit Punkt anfangen auslassen...
Mit os.walk() kommt man da nicht so schnell weiter...
Idee?
Rekursive Funktion mit os.listdir() ?
EDIT: Hm:
Code: Alles auswählen
import os, dircache
media_root = "./media"
def dir_walk(path):
for name in dircache.listdir(path):
if name.startswith("."):
continue
abs_path = os.path.join(path, name)
if not os.path.isdir(abs_path):
continue
yield abs_path
for dir in dir_walk(abs_path):
yield dir
for i in dir_walk(media_root):
print i
Was haltet ihr davon?
Verfasst: Montag 14. Juli 2008, 14:32
von audax
Code: Alles auswählen
import os
found = []
for root, dirs, files in os.walk('blub'):
found.extend(d for d in dirs if not d.startswith('.'))
print found
Verfasst: Montag 14. Juli 2008, 14:35
von jens
Ne, ich brauche den vollen Pfad...
Verfasst: Montag 14. Juli 2008, 14:36
von audax
Code: Alles auswählen
import os
found = []
for root, dirs, files in os.walk('blub'):
found.extend(os.path.join(root, d) for d in dirs if not d.startswith('.'))
print found
Muss man dir denn alles vorkauen?

Verfasst: Montag 14. Juli 2008, 14:38
von jens
Selbst mal ausprobiert? So einfach ist das nicht...
Sowas kommt raus:
Code: Alles auswählen
./media/PyLucid
./media/.svn/tmp
./media/.svn/props
./media/.svn/prop-base
./media/.svn/text-base
./media/.svn/tmp/props
./media/.svn/tmp/prop-base
./media/.svn/tmp/text-base
./media/PyLucid/tiny_mce
./media/PyLucid/internal_page
...
Das Verzeichnis ./media/.svn wird zwar ausgelassen, aber nicht die Unterverzeichnis darin

Verfasst: Montag 14. Juli 2008, 14:48
von audax
Code: Alles auswählen
import os
found = []
for root, dirs, files in os.walk('blub'):
for d in dirs:
if d.startswith('.'):
dirs.remove(d)
found.extend(os.path.join(root, d) for d in dirs)
print found
Dann entfernt man die eben

Verfasst: Montag 14. Juli 2008, 15:00
von jens
Ne, ich glaube os.walk() ist hier nicht angebracht. Es ist langsamer, wenn auch nicht viel:
Code: Alles auswählen
import timeit, os
def dir_walk1(path):
result = []
for name in os.listdir(path):
if name.startswith("."):
continue
abs_path = os.path.join(path, name)
if not os.path.isdir(abs_path):
continue
result.append(abs_path)
sub_dirs = dir_walk1(abs_path)
if sub_dirs:
result += sub_dirs
return result
#_____________________________________________________________________________
def dir_walk2(path):
found = []
for root, dirs, files in os.walk(path):
for d in dirs:
if d.startswith('.'):
dirs.remove(d)
found.extend(os.path.join(root, d) for d in dirs)
return found
#_____________________________________________________________________________
def dir_walk3(path):
found = []
for root, dirs, files in os.walk(path):
for d in dirs:
if d.startswith('.'):
dirs.remove(d)
else:
found.append(os.path.join(root, d))
return found
#_____________________________________________________________________________
loop = 20
tests = (
("dir_walk1('.')", "from __main__ import os, dir_walk1"),
("dir_walk2('.')", "from __main__ import os, dir_walk2"),
("dir_walk3('.')", "from __main__ import os, dir_walk3"),
)
for no, test in enumerate(tests):
print "%s - %s" % (no+1, test[0])
test = timeit.Timer(test[0], test[1])
print "%.2f" % test.timeit(number=loop)
print
Ausgabe:
1 - dir_walk1('.')
0.79
2 - dir_walk2('.')
1.06
3 - dir_walk3('.')
0.97
@audax: dir_walk2() ist deine Variante...
Verfasst: Montag 14. Juli 2008, 15:05
von audax
achso, es geht um jeden Zyklus, das wusste ich nicht!
Ich dachte schon, es geht um Lesbarkeit und Wartbarkeit...wie bin ich blos darauf gekommen...
Verfasst: Montag 14. Juli 2008, 15:13
von noob1
in der eingesparten zeit könnte er die welt retten...
Verfasst: Montag 14. Juli 2008, 15:14
von jens
Meine Variante kann man noch vereinfachen, denn ich if Abfrage kann man sich sparen.
externd ist wohl auch schneller als ein +=
Statt os.listdir nutzte ich auch eigentlich dircache.listdir, was nochmal ein tick schneller ist
Ich nutzte dir_walk2():
Code: Alles auswählen
import timeit, os, dircache
def dir_walk1(path):
result = []
for name in os.listdir(path):
if name.startswith("."):
continue
abs_path = os.path.join(path, name)
if not os.path.isdir(abs_path):
continue
result.append(abs_path)
result.extend(dir_walk1(abs_path))
return result
#_____________________________________________________________________________
def dir_walk2(path):
result = []
for name in dircache.listdir(path):
if name.startswith("."):
continue
abs_path = os.path.join(path, name)
if not os.path.isdir(abs_path):
continue
result.append(abs_path)
result.extend(dir_walk1(abs_path))
return result
#_____________________________________________________________________________
def dir_walk3(path):
found = []
for root, dirs, files in os.walk(path):
for d in dirs:
if d.startswith('.'):
dirs.remove(d)
else:
found.append(os.path.join(root, d))
return found
#_____________________________________________________________________________
loop = 100
tests = (
("dir_walk1('.')", "from __main__ import os, dir_walk1"),
("dir_walk2('.')", "from __main__ import os, dircache, dir_walk2"),
("dir_walk3('.')", "from __main__ import os, dir_walk3"),
)
for no, test in enumerate(tests):
print "%s - %s" % (no+1, test[0])
test = timeit.Timer(test[0], test[1])
print "%.2f" % test.timeit(number=loop)
print
Ergebnis:
Code: Alles auswählen
1 - dir_walk1('.')
4.10
2 - dir_walk2('.')
3.75
3 - dir_walk3('.')
5.07
Finde jetzt nicht, das dir_walk2() wesentlich undurchsichtiger wäre als dir_walk3()...
Später kommt evtl. noch eine "skip-Liste" hinzu...
Verfasst: Montag 14. Juli 2008, 15:16
von audax
Naja, für mich fällt das unter "unnötige Mikrooptimierung".
Verfasst: Montag 14. Juli 2008, 15:19
von BlackJack
Oh bitte Leute, ihr programmiert doch nicht erst seit gestern in Python: Aus einer Liste Elemente entfernen während man darüber iteriert ist eine doofe Idee. Also bitte die ``for``-Schleife durch so etwas hier ersetzen:
Verfasst: Montag 14. Juli 2008, 15:23
von audax
uhm...da war ja was...
Verfasst: Montag 14. Juli 2008, 16:40
von BlackJack
@jens: Vielleicht ist die `os.walk()` Lösung ja auch deswegen geringfügig langsamer, weil bei aufeinander folgenden versteckten Verzeichnissen jedes zweite doch im Ergebnis landet, wenn man ``for`` und `remove()` verwendet.