Verzeichnis liste ohne versteckte Verzeichnisse...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Verzeichnis liste ohne versteckte Verzeichnisse...

Beitragvon jens » Montag 14. Juli 2008, 14:16

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?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Montag 14. Juli 2008, 14:32

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
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Montag 14. Juli 2008, 14:35

Ne, ich brauche den vollen Pfad...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Montag 14. Juli 2008, 14:36

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? :D
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Montag 14. Juli 2008, 14:38

Selbst mal ausprobiert? So einfach ist das nicht...

Sowas kommt raus:
[code=]./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
...[/code]

Das Verzeichnis ./media/.svn wird zwar ausgelassen, aber nicht die Unterverzeichnis darin ;)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Montag 14. Juli 2008, 14:48

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 :D
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Montag 14. Juli 2008, 15:00

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...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Montag 14. Juli 2008, 15:05

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...
noob1
User
Beiträge: 9
Registriert: Mittwoch 9. Juli 2008, 09:24

Beitragvon noob1 » Montag 14. Juli 2008, 15:13

in der eingesparten zeit könnte er die welt retten...
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Montag 14. Juli 2008, 15:14

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=]1 - dir_walk1('.')
4.10

2 - dir_walk2('.')
3.75

3 - dir_walk3('.')
5.07[/code]

Finde jetzt nicht, das dir_walk2() wesentlich undurchsichtiger wäre als dir_walk3()...

Später kommt evtl. noch eine "skip-Liste" hinzu...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Montag 14. Juli 2008, 15:16

Naja, für mich fällt das unter "unnötige Mikrooptimierung".
BlackJack

Beitragvon BlackJack » Montag 14. Juli 2008, 15:19

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:

Code: Alles auswählen

dirs[:] = [d for d if d[0] != '.']
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Montag 14. Juli 2008, 15:23

uhm...da war ja was...
BlackJack

Beitragvon BlackJack » Montag 14. Juli 2008, 16:40

@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.

Wer ist online?

Mitglieder in diesem Forum: __deets__