Liste nach mehreren Strings durchsuchen?

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
shadow07
User
Beiträge: 43
Registriert: Sonntag 22. Februar 2009, 16:29

ich hänge mal wieder:
ich suche in einer Liste nach Suchstring und Endung - funktioniert soweit. Nun möchte ich aber mehrere Endungen als Wahr akzeptieren, wie kann ich das anstellen?

Liste1 = [freund.mpeg, feind.mpg, butter.mpeg, brot.wav, wurst.wrs]
Liste2 = [mpg, mpeg]

Code: Alles auswählen

Endung = "mpg"
Suchstring = "*nd*"
if name.endswith(Endung) is True and fnmatch.fnmatch(name.lower(),Suchstring) is True:
    Dateiliste.append(( name, fullpath ))
Ergebnis:
feind,

Code: Alles auswählen

# funktioniert so natürlich nicht mehr
Endung = "mpg, mpeg"
Suchstring = "*nd*"
if name.endswith(Endung) is True and fnmatch.fnmatch(name.lower(),Suchstring) is True:
    Dateiliste.append(( name, fullpath ))
Wunschergebnis:
freund, feind
ich hab 'ne kastrierte Form von Python, meine Scripte müssen ohne Nachinstallationen auskommen..........
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Code: Alles auswählen

[word for word in liste1 if any(map(lambda x: x in word, liste2))]
Leider geht ``operator.contains`` nicht mit Keyword-Argumenten (wie str1442 schon festgestellt hat), sonst ginge es hübscher.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@shadow07: ``is`` prüft auf Objektidentität, nicht auf Wertegleichheit. Das sollte man wirklich nur in Fällen verwenden, wo man exakt auf ein bestimmtes Objekt prüfen möchte, und das möchte man eigentlich relativ selten. Im Regelfall nur, wenn das Objekt, auf das man prüfen möchte, ein Singleton ist, wie zum Beispiel `None`. Das Konzept von "Wahr" und "Falsch" beschränkt sich in Python aber nicht auf die beiden Objekte, die an die Namen `True` und `False` gebunden sind.

Aber selbst ein ``==`` wäre hier überflüssig, weil die beiden Funktionsaufrufe selbst ja schon Wahrheitswerte zurückgeben, die braucht man also nicht noch einmal mit einem Wahrheitswert zu vergleichen um dann doch nur wieder einen Wahrheitswert zu bekommen.

Ansonsten wirst Du halt die Endungen einzeln prüfen müssen. Eventuell in einer Schleife und die in eine Funktion ausgelagert, damit es nicht zu unübersichlich wird.

Du könntest auch eine Funktion schreiben, die alle Prüfungen für einen Namen enthält, und dann zum Beispiel die neue Dateiliste mit `filter()` aus der alten erstellen.

@Leonidas: `operator.contains()` sollte trotzdem mit `functools.partial()` verwendbar sein, falls es das wäre was Du hübscher fändest, aber ich glaube einfacher wäre dass hier: ``any(x in word for x in liste2)``
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

@BlackJack: Ja, so meinte ich es. Tatsächlich, das würde gehen; ich hatte beim Testen die Reihenfolge der Parameter andersrum und das ging nicht. Natürlich habe ich wiedereinmal viel zu kompliziert gedacht :evil:
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
shadow07
User
Beiträge: 43
Registriert: Sonntag 22. Februar 2009, 16:29

ich habe das jetzt so verwendet:

Code: Alles auswählen

Findliste2 = [element for element in Dateiliste if any(map(lambda x: x in element, self.eEndung2))]
was aber offenbar nicht geht, denn ich bekomme weit mehr Ergebnisse, welche nicht mit Elementen von self.eEndung2 übereinstimmen

@BlackJack
ich habe das ``is` entfernt, danke für den Hinweis

die Endungen einzeln überprüfen bekomme ich nicht hin, weil erstens die Anzahl der Endungen unterschiedlich sein kann (bei einer Suche 3, bei einer anderen Suche 6) und ich zweitens endlose or-Ketten vermeiden möchte

ich habe praktisch eine vorgefilterte Liste mit Dateinamen, welche dem Suchstring entsprechen. Die Liste will ich nun nochmal filtern nach einer oder mehreren per Variablen-Liste übergebenen Endungen
(oder alles in einem Rutsch wäre genialer)
ich hab 'ne kastrierte Form von Python, meine Scripte müssen ohne Nachinstallationen auskommen..........
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Blackjack hat geschrieben:[...] einfacher wäre dass hier: ``any(x in word for x in liste2)``
@shadow07: Und warum benutzt du dann die kompliziertere Variante?
shadow07
User
Beiträge: 43
Registriert: Sonntag 22. Februar 2009, 16:29

Und warum benutzt du dann die kompliziertere Variante?
vermutlich, weil ich zu dämlich bin den Codefetzen sinnvoll zu benutzen :(
(und eine Suche mir ein paar hundert Seiten beschert wo alle bisher gelesenen any als Kommentar oä enthielten)
ich hab 'ne kastrierte Form von Python, meine Scripte müssen ohne Nachinstallationen auskommen..........
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Code: Alles auswählen

[word for word in liste1 if any(x in word for x in liste2)]
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

shadow07
User
Beiträge: 43
Registriert: Sonntag 22. Februar 2009, 16:29

also beide Varianten gehen nicht (Ergebnis nichts):

Code: Alles auswählen

for word in Dateiliste:
				if any(x in word for x in self.eEndung2):
					Dateiliste2.append(word)

Code: Alles auswählen

Dateiliste2 = [word for word in Dateiliste if any(x in word for x in self.eEndung2)]
ich hab 'ne kastrierte Form von Python, meine Scripte müssen ohne Nachinstallationen auskommen..........
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mach mal ein

Code: Alles auswählen

print repr(Dateiliste)
print repr(self.eEndung2)
in deinem Code und poste das Ergebnis.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
shadow07
User
Beiträge: 43
Registriert: Sonntag 22. Februar 2009, 16:29

Mach mal ein
ist nicht so einfach, da einiges importiert wird was nur auf der GUI läuft, müsste alles zerlegen - aber so läufts:

Code: Alles auswählen

if fnmatch.fnmatch(name.lower(),Suchstring):
    if any(x in name for x in self.eEndung):
        Dateiliste.append(( name, fullpath ))
also hat mich dein Print-Hinweis doch auf die Lösung gebracht, denn die Liste ist offenbar ungeeignet, wenn ich aber sofort am Anfang prüfen lasse dann gehts ja

vielen Dank euch :D
ich hab 'ne kastrierte Form von Python, meine Scripte müssen ohne Nachinstallationen auskommen..........
Antworten