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

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