Seite 1 von 1

Problem mit selbstgebauter Suchfunktion

Verfasst: Mittwoch 25. Juli 2007, 11:28
von Klemens
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")

Verfasst: Mittwoch 25. Juli 2007, 11:34
von EnTeQuAk
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

Verfasst: Mittwoch 25. Juli 2007, 11:44
von Klemens
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")

Re: Problem mit selbstgebauter Suchfunktion

Verfasst: Mittwoch 25. Juli 2007, 12:12
von helduel
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

Verfasst: Mittwoch 25. Juli 2007, 12:16
von helduel
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

Verfasst: Mittwoch 25. Juli 2007, 12:18
von EnTeQuAk
Das bringt nichts. Das break wird nie erreicht, weil die Funktion bei return verlassen wird.
Stimmt, total vergessen. Mein Fehler :)

Verfasst: Mittwoch 25. Juli 2007, 12:30
von Klemens
Juhuu!! THX euch allen, es geht... :D

Verfasst: Mittwoch 25. Juli 2007, 14:02
von 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

Verfasst: Mittwoch 25. Juli 2007, 15:01
von Zizibee
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):
?

Verfasst: Mittwoch 25. Juli 2007, 15:14
von 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).

Verfasst: Mittwoch 25. Juli 2007, 15:14
von 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.