Seite 1 von 1
"filter" funktioniert nicht in gewünschter Weise
Verfasst: Montag 27. Februar 2012, 15:29
von api
Hallo,
ich möchte gerne aus einer Liste, die mit Dateinamen gefüllt ist, diejenigen raussuchen, die die Dateiendung (Suffix) "msi" haben.
Dazu habe ich mir folgendes Script gedacht:
Code: Alles auswählen
#! /usr/bin/env python
import os
import glob
AllFileList = ['C:\\tmp\\test\\new\\Putty.log', 'C:\\tmp\\test\\new\\CSES.msi', 'C:\\tmp\\test\\new\\Putty_7_sna.log', 'C:\\tmp\\test\\new\\wrapper.css']
print AllFileList
for single_file in AllFileList:
if filter(single_file.endswith, "msi"):
print "Filter is positive! => File: %s" % single_file
Und das kommt raus:
Code: Alles auswählen
C:\tmp>test.py
['C:\\tmp\\test\\new\\Putty.log', 'C:\\tmp\\test\\new\\CSES.msi', 'C:\\tmp\\test\\new\\Putty_7_sna.log', 'C:\\tmp\\test\
\new\\wrapper.css']
Filter is positive! => File: C:\tmp\test\new\CSES.msi
Filter is positive! => File: C:\tmp\test\new\wrapper.css
Erwarten würde ich aber nur die Datei "C:\tmp\test\new\CSES.msi"...
Warum findet der auch die "wrapper.css"-Datei?
CU,
API
Re: "filter" funktioniert nicht in gewünschter Weise
Verfasst: Montag 27. Februar 2012, 15:41
von webspider
filter filtert mithilfe einer Funktion (lambda bietet sich da insbesondere an) aus einer Liste Elemente aus. Hier eine funktionierende Variante deines Beispiels:
Code: Alles auswählen
file_list = ['C:\\tmp\\test\\new\\Putty.log', 'C:\\tmp\\test\\new\\CSES.msi', 'C:\\tmp\\test\\new\\Putty_7_sna.log', 'C:\\tmp\\test\\new\\wrapper.css']
print file_list
print filter(lambda x: x.endswith("msi"), file_list)
Re: "filter" funktioniert nicht in gewünschter Weise
Verfasst: Montag 27. Februar 2012, 15:41
von pillmuncher
So, wie du filter() verwendest, testest du, ob single_file mit einem der Buchstaben "m", "s", oder "i" endet, aber nicht, ob single_file mit "msi" endet. Richtig wäre es so:
Code: Alles auswählen
for single_file in AllFileList:
if single_file.endswith("msi"):
print "Filter is positive! => File: %s" % single_file
Re: "filter" funktioniert nicht in gewünschter Weise
Verfasst: Montag 27. Februar 2012, 15:44
von EyDu
Und solltest du nach über 100 Posts nicht mittlerweile gelernt haben, dass es Codetags für Python gibt?

Re: "filter" funktioniert nicht in gewünschter Weise
Verfasst: Montag 27. Februar 2012, 15:44
von deets
Du hast filter nicht verstanden. filter bekommt ein Praedikat, und ein iterierbares Objekt - und liefert die Liste der Objekte, bei denen das Praedikat True liefert.
Du aber iterierst schon ueber deine Liste von Dateinamen, und statt einfach "if name.endwith("msi")" zu machen, hast du einen filter-Ausdruck gebaut, der
- ueber die Buchstaben "m", "s" und "i" iteriert
- schaut, ob der aktuelle Name auf einen davon endet.
Das stimmt natuerlich auch bei "css".
Ich wuerde dir hier auch generell stattdessen zu einer Listcomprehension (oder gen-exp) raten, statt das etwas antiquierte filter zu benutzen (das hat immer noch seinen Sinn, aber anderswo):
Code: Alles auswählen
msis = [name for name in namensliste if name.endswith("msi")]
Dann kann man natuerlich noch statt endwith fnmatch oder os.path.splitext() verwenden - das waere noch besser, denn so findest du ja auch Dateien, die nicht auf ".msi" enden.
Re: "filter" funktioniert nicht in gewünschter Weise
Verfasst: Montag 27. Februar 2012, 16:01
von api
Danke schonmal für eure Erklärungen.
Ich habe das jetzt mal an dem Beispiel mit dem Suffix "msi" aufgehängt, um das Problem deutlich einzuschränken.
Und ihr habt Recht - "filter" hatte ich nicht wirklich verstanden. Aber ich habe "filter" verwendet, weil ich nicht nur nach "msi"-Dateien suche, sondern evtl auch nach anderen Dateiendungen (zB "log", ...) - und da man "filter" einen Tupel übergeben kann, hielt ich das für ne brauchbare Lösung...
Kann mir dafür noch jemand nen Lösungsansatz nennen? (Alle Dateiendungen, die infrage kommen, stehen in einem Tupel)
Re: "filter" funktioniert nicht in gewünschter Weise
Verfasst: Montag 27. Februar 2012, 16:07
von pillmuncher
@api:
Code: Alles auswählen
for single_file in AllFileList:
if any(single_file.endswith(word) for word in ('msi', 'abc', 'def')):
print "Filter is positive! => File: %s" % single_file
Im Übrigen schließe ich mich deets Meinung an, wenn er schreibt, dass fnmatch oder os.path.splitext() besser wären, als str.endswith().
Re: "filter" funktioniert nicht in gewünschter Weise
Verfasst: Montag 27. Februar 2012, 16:07
von api
@eyDu: Das könnte ich wirklich mal in Angriff nehmen...
