Python auflisten aller jpg dateien in einem Ordner

OP #7739448
Lesenswert?

Hallo, ich habe eine Funktion in python

1
from os import listdir
2
from os.path import isfile, join
3

4
jpg_files = [f for f in listdir(foto_path) if isfile(join(foto_path, f))]
5
print(jpg_files)

welche mir alle Dateien aus dem Ordner foto_path ausgibt.

Im Ordner foto_path gibt es noch einen weitern Ordner, welcher nicht geparst wird (möchte ich auch nicht). Allerdings gibt es .txt dateien, welche ich nicht in der Liste jpg_files haben möchte. Wie kann ich das am besten lösen?

Eine For-Schleife um auf die Endung zu achten, wollte ich vermeiden

#7739494
Lesenswert?

Εrnst B. schrieb:

and f.endswith('.jpg')]

... würde ich noch mit '.jpeg' erweitern, das begegnet einem in freier Wildbahn durchaus auch.

Müsste also so aussehen:

1
pg_files = [f for f in listdir(foto_path) if isfile(join(foto_path, f)) and f.endswith('.jpg') or f.endswith('.jpeg')]

Ist "endswith" case-sensitiv? Wenn ja, wird es die unter Windows möglichen ".JPG" oder ".JpEg" nicht finden.

Gast #7739518
Lesenswert?

Harald K. schrieb:

Εrnst B. schrieb:

and f.endswith('.jpg')]

... würde ich noch mit '.jpeg' erweitern, das begegnet einem in freier Wildbahn durchaus auch. Müsste also so aussehen:

pg_files = [f for f in listdir(foto_path) if isfile(join(foto_path, f)) and f.endswith('.jpg') or f.endswith('.jpeg')]

Ist "endswith" case-sensitiv? Wenn ja, wird es die unter Windows möglichen ".JPG" oder ".JpEg" nicht finden.

Auf die Idee den Dateityp anhand der Endung zu bestimmen kommen nur Windows-User. python-magic oder filetype sind die richtigen Wege.

#7739632
Lesenswert?

Εrnst B. schrieb:

1
> jpg_files = [f for f in listdir(foto_path) if isfile(join(foto_path, f)) 
2
> and f.endswith('.jpg')]
3
>

Heutzutage vielleicht schöner:

1
from pathlib import Path
2

3
jpg_files = (f for f in Path(foto_path).glob('*') 
4
             if f.is_file() and f.name.lower().endswith('webp'))

Diese Variante verwendet keine Liste, sondern einen Generator. Dadurch werden nicht alle Dateinamen in den Arbeitsspeicher geladen, was bei sehr vielen und / oder sehr langen Dateinamen weniger Speicher belegt. Außerdem verwendet die Variante das seit Python 3.4 enthaltene und empfohlene Standardmodul Pathlib. Eine rekursive Version geht mit der Methode rglob() statt glob().

#7739681
Lesenswert?

Ein T. schrieb:

Heutzutage vielleicht schöner: from pathlib import Path jpg_files = (f for f in Path(foto_path).glob('*') if f.is_file() and f.name.lower().endswith('webp'))

Die Pathlib wird bei den Pythonentwicklern als moderne Alternative zu os.path gesehen. Allerdings würde ich denn Ausdruck nicht mit glob, sondern mit iterdir schreiben, da es sich ja nicht um eine rekursive Suche handeln soll. Außerdem empfehle ich anstelle von name die property suffix zu verwenden so das der Generator dann wie folgt aussieht.

1
 jpg_files = (f for f in Path(fotopath).iterdir() 
2
                if f.is_file() and f.suffix.lower() == '.jpg')
Gast #7739813
Lesenswert?

Chandler B. schrieb:

1
jpg_files = [f for f in listdir(foto_path) if isfile(join(foto_path, f))]
2
print(jpg_files)

Wann war eigentlich der Tag, an dem man beschlossen hat, dass man in Python den Code mit mehr Klammern und Verschachtelungen als in C schreiben muss? Wurde PEP 8 für ungültig erklärt?

#7739819
Lesenswert?

Re D. schrieb:

Chandler B. schrieb:jpg_files = [f for f in listdir(foto_path) if isfile(join(foto_path, f))] print(jpg_files)

Wann war eigentlich der Tag, an dem man beschlossen hat, dass man in Python den Code mit mehr Klammern und Verschachtelungen als in C schreiben muss? Wurde PEP 8 für ungültig erklärt?

Ich sehe da nur eine list comprehension in ihrer fast einfachsten Art. Diese halt zusätzlich mit einer simplen Bedingung.

#7739852
Lesenswert?

Re D. schrieb:

Dann übersiehst du mindestens den Aufruf von 2 Funktionen.

<Loriot>Ach!</Loriot>

Wie soll ich's sagen? So etwas dient nicht dem Eigenzweck, sondern soll etwas bewirken. Ganz ohne Daten – von irgendwo her bezogen – geht's dann ja wohl eh nicht.

Aber um meine Aussage noch ein wenig klarer zu machen: Wenn's in eine Zeile passt und noch nicht einmal ein Umbruch erforderlich ist, dann lohnt es sich sicherlich noch nicht einmal darüber nachzudenken.

#7740042
Lesenswert?

Chandler B. schrieb:

Eine For-Schleife um auf die Endung zu achten, wollte ich vermeiden

Aber einen Test wirst du brauchen, und du könntest auch eine While-Schleife nehmen.

Wenn man keinen Test haben will, könnte man die Menge der Nichtgewollten auch von Hand rausnehmen - oder eben auch automatisch ;)

Je nach Betriebsystem bieten sich auch noch verschiedene andere Hilfsmöglichkeiten an.

#7740056
Lesenswert?

Harald K. schrieb:

Auf die Idee, statt einfach nur Dateinamen anzusehen, den Aufriss zu treiben, jede Datei anzufassen und einen Teil davon zu lesen, um ihn zu analysieren, kommen auch nur Zeitgenossen, denen Performance komplett scheißegal ist.

Tja, man kann's entweder schnell oder eben gut machen.

PS. Aus gewöhnlich gut unterrichteten Kreisen ist durchgesickert, dass OS heutzutage einen Cache nutzen. (Kein BS)

#7740137
Lesenswert?

Norbert schrieb:

dass OS heutzutage einen Cache nutzen.

Und in dem landen noch nicht gelesene Dateien irgendwie automagisch? Ist ja interessant, so ein Cache.

Wenn man den gleichen Kram /mehrfach hintereinander/ anstellt, dann hilft so ein Cache, keine Frage, aber ...

Das ist so, als ob ich, statt auf einen Buchrücken zu gucken, auf dem der Autorenname draufsteht, das Buch aus dem Regal ziehen und aufschlagen muss, um die bibliographischen Angaben darin zu finden, denen ich dann den Autorennamen entnehm.

Kann man so machen, aber auf so ein Verfahren auch noch stolz zu sein und mit Häme auf die Untersuchung von Dateinamenserweiterungen zu blicken, stellt einen in ein recht fragwürdiges Zwielicht. Wenn die eigene Unterhose zwischen den Knien hängt, sollte man andere nicht auf schlechtsitzende Kleidung hinweisen.

Moderator #7740138
Lesenswert?

Re D. schrieb:

Chandler B. schrieb:

jpg_files = [f for f in listdir(foto_path) if isfile(join(foto_path, f))] print(jpg_files)

Wann war eigentlich der Tag, an dem man beschlossen hat, dass man in Python den Code mit mehr Klammern und Verschachtelungen als in C schreiben muss?

Zeig doch mal, wie du dasselbe in C mit weniger Klammern hinbekommst.

In Haskell könnte man auf sämtliche Klammern verzichten (auch wenn man das in der Praxis nicht tun würde):

1
main = getDirectoryContents fotoPath >>= filterM f >>= print
2
       where f = doesFileExist . combine fotoPath

Aber in C? Wie soll das gehen?

#7740171
Lesenswert?

Harald K. schrieb:

Und in dem landen noch nicht gelesene Dateien irgendwie automagisch? Ist ja interessant, so ein Cache.

Die Sülze kannst du dir getrost sparen.

Nur eben nicht, wenn man schnell den Computer hochfährt, ein Listing anfordert, die Zeit misst — ach du meine Güte, das dauert ja Sekunden – und dann den Computer sofort wieder herunter fährt. Dein geschilderter Fall ist dementsprechend ein typisches Anwenderszenario.

#7740192
Lesenswert?

Harald K. schrieb:

Norbert schrieb:

Nur eben nicht, wenn man schnell den Computer hochfährt, ein Listing anfordert, die Zeit misst — ach du meine Güte, das dauert ja Sekunden – und dann den Computer sofort wieder herunter fährt.

Hmm. Ich glaube nicht, daß Du wirklich verstanden hast, was ein Cache ist.

Harald, vermutlich ist dir nicht mehr zu helfen, da es dir wohl hauptsächlich darum geht irgendwie Contra zu geben.

Ich versuche es trotzdem. Wenn man, wie ein normaler Benutzer seinen Computer eingeschaltet lässt und längere Zeit damit arbeitet, dann wird bei jeder Leseoperation der Cache langsam gefüllt (und ja, Elemente werden auch wieder verworfen wenn das RAM für andere Dinge genutzt werden soll.

Beim ersten Lesen eines Verzeichnisses landen die Informationen vom Drive ebenfalls im Cache. Und bei allen weiteren Operationen wird eben dieser verwendet und das Drive hat Pause.

Ergebnis: Beim ersten Mal etwas langsamer, danach Wieselflink.

Dafür wird eine ausführbare Datei nicht fälschlicherweise als pdf oder jpeg angezeigt. Aber jeder wie er's braucht.

#7740238
Lesenswert?

Rbx schrieb:

Chandler B. schrieb:

Eine For-Schleife um auf die Endung zu achten, wollte ich vermeiden

Aber einen Test wirst du brauchen, und du könntest auch eine While-Schleife nehmen.

Allerdings wäre die Verwendung von while hier extrem bescheuert.

Bei wohlerzogenen, also konsistent gleichen Dateinamen würde allerdings auch

[code] from pathlib import Path

jpg_files = Path(foto_path).glob('.jpg') [code]

gehen (oder mit der entsprechenden Endung anstelle von '.jpg').

#7741599
Lesenswert?

Norbert schrieb:

Beim ersten Lesen eines Verzeichnisses landen die Informationen vom Drive ebenfalls im Cache. Und bei allen weiteren Operationen wird eben dieser verwendet und das Drive hat Pause.

Das ist zwar alles korrekt, allerdings helfen einem diese Daten im Cache eben auch nur dann, wenn man jpg-Dateien ausschließlich an ihrem Namen bzw. der Extension zu erkennen versucht und nicht daran, was sie jeweilige Datei tatsächlich enthält. Aber genau diese Frage war der Ausgangspunkt dieser Diskussion, wie man hier sehen kann; im Original hatte Harald K. allerdings die dritte Zeile von Re D. vor seiner Antwort nicht mehr mitzitiert:

Harald K. schrieb:

Re D. schrieb:

Auf die Idee den Dateityp anhand der Endung zu bestimmen kommen nur Windows-User. python-magic oder filetype sind die richtigen Wege.

Auf die Idee, statt einfach nur Dateinamen anzusehen, den Aufriss zu treiben, jede Datei anzufassen und einen Teil davon zu lesen, um ihn zu analysieren, kommen auch nur Zeitgenossen, denen Performance komplett scheißegal ist.

Norbert schrieb:

Dafür wird eine ausführbare Datei nicht fälschlicherweise als pdf oder jpeg angezeigt.

Dazu - nachdem ich das jetzt extra probiert habe - ein sehr klares: Jain!

Konkret: Ich habe eine hier am Rechner rumkugelnde, ausführbare Datei namens Setup.exe mal in Setup.exe.pdf umbenannt und voila, schon wurde sie mit einem wunderschönen PDF-Icon angezeigt. Allerdings ist sie jetzt auch aus der Desktop-Umgebung (im Ggs. zu einem Terminalfenster) nicht mehr mit Doppelklick ausführbar; insofern könnte man - aus der Sicht eines nur Desktop-Nutzers - sagen, daß es nun auch keine ausführbare Datei ist.

Gast #7741604
Lesenswert?

Walter T. schrieb:

Meine Güte. Man muss die ersten vier Bytes einer Datei lesen, um ein JPG zu erkennen. Wenn man sich das nicht leisten kann, hat man noch ganz andere Probleme.

Man kann sich ja man anschauen, was der Dateimanager von Windows alles so macht, nachdem er das Inhaltsverzeichnis gelesen hat.

#7741643
Lesenswert?

Michi S. schrieb:

Das ist zwar alles korrekt, allerdings helfen einem diese Daten im Cache eben auch nur dann, wenn man jpg-Dateien ausschließlich an ihrem Namen bzw. der Extension zu erkennen versucht und nicht daran, was sie jeweilige Datei tatsächlich enthält.

Was lässt dich glauben, dass der erste Scan der jpgs nicht auch im Cache landet?

Jens G. schrieb:

Nein, man muß die ersten 512B oder gar 4kB lesen, um die ersten paar Bytes lesen zu können. Und das dauert halt ein bißchen,

Exakt: Ein bisschen! Genauer gesagt, der (physikalische) Lesevorgang dauert bei einem Byte präzise genauso lange wie bei einem kompletten Sektor.

Gast #7741670
Lesenswert?

Michi S. schrieb:

Sicht eines nur Desktop-Nutzers - sagen, daß es nun auch keine ausführbare Datei ist.

Ein Python- Skript ist aber kein Desktopnutzer.

Harald K. schrieb:

Auf die Idee, statt einfach nur Dateinamen anzusehen, den Aufriss zu treiben, jede Datei anzufassen und einen Teil davon zu lesen, um ihn zu analysieren, kommen auch nur Zeitgenossen, denen Performance komplett scheißegal ist.

Wie viele Mio Dateien sind es denn? Mir ist ein korrektes Ergebnis lieber als 2 Sekunden Laufzeit. Wenn es auf solche Performance ankommt ist Python ggf. auch fie falsche wahl. Somit ist deine Grundannahme (Performance ist relevant) falsch. Es bleibt deine Engstirnigkeit weil du meinst du wärst besser.

#7741691
Lesenswert?

Re D. schrieb:

Jens G. schrieb:

Mittlerweile? Schon seit eh und je, seit es NTFS gibt ...

Und trotzdem geht geht es nicht default die Dateien Windows.txt und windows.txt in einem Ordner zu haben. Also ist das "Schon seit eh und je" nur sehr begrenzt durch praktische Erfahrung belegt.

Welche praktische Erfahrung? NTFS behält einfach die groß-/Kleinschreibung bei, unterscheidet die aber nicht. Das ist schon seit 30 Jahren so. Mir ist aber nicht bekannt, dass sich daran etwas "mittlerweile" geändert haben soll.

#7741692
Lesenswert?

Re D. schrieb:

Norbert schrieb:

Lerne die Basics, dann, falls noch gewünscht, meckere.

Lerne erklären, wieso sind es Methoden und keine Funktionen? Das wäre hilfreich.

Alles Erforderliche ist bereits dokumentiert und steht der Allgemeinheit zur Verfügung. Du wirst verstehen, dass ich das ungerne noch einmal machen möchte. Aber hier ist die Referenz/Dokumentation/Tutorial.

https://docs.python.org/3/tutorial/controlflow.html#defining-functions

https://docs.python.org/3/tutorial/classes.html#

Gast #7741698
Lesenswert?

Norbert schrieb:

Alles Erforderliche ist bereits dokumentiert und steht der Allgemeinheit zur Verfügung. Du wirst verstehen, dass ich das ungerne noch einmal machen möchte. Aber hier ist die Referenz/Dokumentation/Tutorial. https://docs.python.org/3/tutorial/controlflow.html#defining-functions https://docs.python.org/3/tutorial/classes.html#

Ja, und wir stellen fest, das es dich Funktionen sind: https://docs.python.org/3/library/os.path.html

"This module implements some useful functions on pathnames."

Oder wo siehst du das zu join gehörige Objekt?

#7741700
Lesenswert?

Re D. schrieb:

Jens G. schrieb:

Welche praktische Erfahrung? NTFS behält einfach die groß-/Kleinschreibung bei, unterscheidet die aber nicht. Das ist schon seit 30 Jahren so. Mir ist aber nicht bekannt, dass sich daran etwas "mittlerweile" geändert haben soll.

Ja, das war aber Deine Aussage, dass es das wäre. Ich dachte nur, dass Du es nicht "ganz so case sensitiv" meintest ...

Dann ist es nicht case senstive. Schau hier: https://learn.microsoft.com/de-de/windows/wsl/case-sensitivity

Ja, das ist aber auch nur so ein drangestöpseltes Feature, um das WSL realisieren zu können. Nicht gerade für den Normalbetrieb empfohlen ...

Gast #7741708
Lesenswert?

Jens G. schrieb:

Ja, das ist aber auch nur so ein drangestöpseltes Feature, um das WSL realisieren zu können. Nicht gerade für den Normalbetrieb empfohlen ...

Ja aber wenn man hier schreibt, Windows wäre nicht case sensitive, dann kommt sofort jemand wie Nobert oder Ein T. Und lässt den Oberlehrer raus hängen.

#7741711
Lesenswert?

Re D. schrieb:

Jens G. schrieb:

Ja, das ist aber auch nur so ein drangestöpseltes Feature, um das WSL realisieren zu können. Nicht gerade für den Normalbetrieb empfohlen ...

Ja aber wenn man hier schreibt, Windows wäre nicht case sensitive, dann kommt sofort jemand wie Nobert oder Ein T. Und lässt den Oberlehrer raus hängen.

Du hast ein gehöriges Wahrnehmungsproblem. Weshalb sollte ich mich mit so etwas wie Windows beschäftigen?

Gast #7741721
Lesenswert?

Norbert schrieb:

Re D. schrieb:

Lenk mal nicht ab

Oh das habe ich nicht. Ich habe nur auf eine dumme Bemerkung reagiert.

Okay, dann sehen wir da den Aufruf von 3 Funktionen und den Vorwurf, dass ich die Basics lernen soll, ziehst du zurück und schickst ihn an Ein T.

Im übrigen war die Bemerkung nicht dumm sondern treffsicher, den der Hund hat gebellt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren