Problem mit selbstgebauter Suchfunktion

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.
Antworten
Klemens
User
Beiträge: 8
Registriert: Mittwoch 25. Juli 2007, 10:58

Hallo zusammen!

Ich versuch momentan eine Suchfunktion zu bastln. Leider wird die Function nicht beendet, wenn er was gefunden hat...

Könnt ihr mir helfen?

Danke im voraus!

Hier ist der Code:

Code: Alles auswählen

import glob, os

def suche(path, filename):
    dateien = glob.glob(path + os.sep + '*')
    for a in dateien:
        if(os.path.isdir(a)):
            suche(a, filename)
        else:
            datei = a
            dateiname = a.split(os.sep)[-1]
            if(dateiname == filename):
               return a
                    
suche("M:", "HelloWorld.txt")
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Rein theoretisch sollte ein einfaches `break` hinter Zeile 12 reichen.
Denn

Code: Alles auswählen

In [1]: for i in xrange(0, 100):
   ...:     print i
   ...:     if i == 50:
   ...:         break
Funktioniert ja auch :)


MfG EnTeQuAk
Klemens
User
Beiträge: 8
Registriert: Mittwoch 25. Juli 2007, 10:58

Hallo EnTeQuAk,

danke für die rasche Antwort! Leider hilft dass auch nicht weiter...

Code: Alles auswählen

import glob, os

def suche(path, filename):
    dateien = glob.glob(path + os.sep + '*')
    for a in dateien:
        if(os.path.isdir(a)):
            suche(a, filename)
        else:
            datei = a
            dateiname = a.split(os.sep)[-1]
            if(dateiname == filename):
               return a
               break
                   
suche("M:", "HelloWorld.txt")
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

die Funktion sollte sich eigentlich schon beenden, nur du bekommst keinen Wert zurück. Wenn du auf ein Verzeichnis stößt, dann wertest du nicht aus, ob in diesem Verzeichnis die gesuchte Datei steckt; du rufst die suche-Funktion lediglich auf.

Versuch mal:

Code: Alles auswählen

import glob, os

def suche(path, filename):
    dateien = glob.glob(path + os.sep + '*')
    for a in dateien:
        if(os.path.isdir(a)):
            value = suche(a, filename)
            if value:
                return value
        else:
            datei = a
            dateiname = a.split(os.sep)[-1]
            if(dateiname == filename):
               return a
                    
suche("M:", "HelloWorld.txt")
Gruß,
Manuel
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin!
EnTeQuAk hat geschrieben:Rein theoretisch sollte ein einfaches `break` hinter Zeile 12 reichen.
Denn

Code: Alles auswählen

In [1]: for i in xrange(0, 100):
   ...:     print i
   ...:     if i == 50:
   ...:         break
Funktioniert ja auch :)


MfG EnTeQuAk
Das bringt nichts. Das break wird nie erreicht, weil die Funktion bei return verlassen wird.

Gruß,
Manuel
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Das bringt nichts. Das break wird nie erreicht, weil die Funktion bei return verlassen wird.
Stimmt, total vergessen. Mein Fehler :)
Klemens
User
Beiträge: 8
Registriert: Mittwoch 25. Juli 2007, 10:58

Juhuu!! THX euch allen, es geht... :D
lunar

os.walk existiert, es besteht kein Grund, die Rekursion eigenhändig zu schreiben. Ebenso gibt es os.path.basename, man muss Dateinamen also auch nicht eigenhändig splitten.

Meine Version:

Code: Alles auswählen

def find_all_files(path, filename):
    """Iterates over all files with `filename` in `path`"""
    for root, directories, files in os.walk(path):
        for match in (os.path.join(root, f) for f in files if f == filename):
            yield match

for match in find_all_files('/home/foo', 'myfile'):
    print match
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Ich finde die for-Schleifen in Python ja echt interessant, was man da so alles reinpacken kann. Leider versteh ich die meistens nicht :oops:
Was macht denn die Zeile

Code: Alles auswählen

        for match in (os.path.join(root, f) for f in files if f == filename):
?
lunar

Zizibee hat geschrieben:Ich finde die for-Schleifen in Python ja echt interessant, was man da so alles reinpacken kann. Leider versteh ich die meistens nicht :oops:
Was macht denn die Zeile

Code: Alles auswählen

        for match in (os.path.join(root, f) for f in files if f == filename):
?
Der geklammerte Ausruck ist eine Generator Expression. Dieser Ausdruck funktioniert genauso wie eine LC, mit dem Unterschied, dass eine LC eine Liste erzeugt, während dieser Ausdruck ein Generator-Objekt erstellt (wie eine Funktion, die das yield Statement enthält).
BlackJack

In ``for``-Schleifen kann man eigentlich nur "iterables" reinpacken. In diesem Fall ist es ein Generator-Ausdruck. Ist im Grunde wie eine "list comprehension" mit runden statt eckigen Klammern nur das nicht erst die ganze Liste auf einmal aufgebaut wird, sondern die Elemente der Reihe nach erzeugt und dann in der Schleife verarbeitet werden.

Der Generator-Ausdruck lässt es sich hier recht einfach "lesen":

(os.path.join(root, f) for f in files if f == filename)

Verbinde die Pfade `root` und `f` für jedes `f` aus `files` wenn `f` == `filename` ist.
Antworten