@UlfZibis: next() ist hier eher als “Operator“ zu sehen, denn das Verhalten kann man überladen. Und es ist keine Methode (mehr) weil gerade in Datenstrukturen ja gerne mal ein next-Attribut auf den nächsten Knoten in der Liste oder dem Baum verweist. Da muss man sich dann keinen anderen Namen für ausdenken.
Bash-Skript: jeder 2. Dateipfad wird am Anfang merkwürdig abgeschnitten
|
Ehemalige
Anmeldungsdatum: Beiträge: 4784 Wohnort: Berlin |
|
||||||
|
Anmeldungsdatum: Beiträge: 2149 Wohnort: Gelsenkirchen |
Ich hätte das einfach mit any() auf der Rückgabe von glob() gelöst, wenn es wirklich nur darum geht, ob der Ordner mindestens eine Datei mit einer bestimmten Endung enthält. any() hört direkt auf, sobald es das erste wahre Element sieht, in diesem Fall also das erste Element des von glob() gelieferten Iterators. Mit next() finde ich es dafür deutlich umständlicher, weil mich ja das Resultat von next() nicht wirklich interessiert, sondern nur die Tatsache, dass es überhaupt eine zutreffende Datei gibt. Und dass glob() nicht von sich aus eine Liste erzeugt, hätte man sich relativ schnell durch Ansehen des bereits erwähnten Beispiels aus der Doku erschließen können:
Da würde ja wohl kaum list() stehen, wenn glob() das schon machen würde. Um es noch einmal ganz deutlich hinzuschreiben, das zuvor gezeigte contains() ist wie:
... und somit ein kurzer Einzeiler, den man auch direkt in der LC unterbringen kann. Auch das schreibe ich gerne noch einmal hin:
Den f-String habe ich mal lieber weggelassen, damit es für manchen Leser nicht zu anspruchsvoll wird. Wobei man bestimmt noch ein paar Nanosekunden herauskitzeln könnte, wenn vorab das Globbing-Muster ("*" + extension) zusammensetzt. 😀 |
||||||
|
Anmeldungsdatum: Beiträge: 2149 Wohnort: Gelsenkirchen |
Um meine vermeintliche Scharfsinnigkeit ging es mir nicht. Ich wollte dich zum selber Recherchieren und Mitdenken anregen. Dass ich mich etwas im Ton vergriffen haben könnte, tut mir leid. Ich setze manchmal vielleicht zu viel Vorwissen voraus. |
||||||
|
(Themenstarter)
Anmeldungsdatum: Beiträge: 3440 Wohnort: Köln |
Oh, das ist ja noch eleganter. Tolle Zusammenarbeit hier.
Ja das habe ich ja mittlerweile auch kapiert, aber danke für die detaillierten Ausführungen.
Da das Muster hier nur einmal verwendet wird, dürfte das nix bringen 😉 Und selbst wenn doch würde ich doch mal vermuten, dass der Optimierer das merkt, und dafür das Zwischenergebnis cached.
Ganz lieben Dank, das nehme ich gerne an. Ja es war tatsächlich der Ton, der mich störte, vor allem die gehäuften DU-Titulierungen und -Unterstellungen. Und anders herum gesehen bin wohl auch ich von zu viel "Vorwissen" ausgegangen, nämlich warum ich das "an anderer Stelle" schon benutzte Konstrukt gerade nicht benutzen wollte, denn das baute mit
Genau da steht eben weder, welchen Objekt-Typ |
||||||
|
Anmeldungsdatum: Beiträge: 2149 Wohnort: Gelsenkirchen |
Das Vorgehen ist jetzt aber hoffentlich klar geworden. Die Schleife zur Bearbeitung des Iterators wird innerhalb der LC untergebracht, indem man eine Funktion dafür benutzt. Entweder eine selbstgeschriebene so wie du es gemacht hast oder eine bereits in Python eingebaute Funktion wie any() oder all(). Diese beiden arbeiten mit der sogenannten Kurzschlussauswertung und steigen unmittelbar aus, sobald das Ergebnis für den Gesamtausdruck feststeht. So steigt any() wie gesagt beim ersten wahren Element aus, weil dies bereits den Sinn der Logik, die hinter any() steckt, erfüllt. Nur wenn erst das letzte Element wahr ist und alle vorherigen falsch sind, dann muss any() die komplette Schleife durchlaufen. Es muss sich eben so lange Elemente "angucken" bis eins davon wahr ist. Sollte selbst das letzte Element falsch sein, dann liefert es als Gesamtausdruck "False". Umgekehrt ist es bei all(): Hier will ich als Aufrufer der Funktion wissen, ob alle Elemente wahr sind. Somit kann diese Funktion im Umkehrschluss früh aussteigen, sobald sie auf ein falsches Element trifft, weil der Gesamtausdruck bereits an dieser Stelle schon "False" sein muss. In der LC arbeitet man somit einerseits mit der ausgeschriebenen for-Schleife und verwendet zusätzlich im if-Teil zum Überprüfen der gewünschten Bedingung eine "versteckte" Schleife. Denn was any() und all() intern machen, ist auch wieder eine Schleife, nur dass du diese Schleife nicht unmittelbar im Code erkennen kannst. Genau auf diesem Wege kommst du dann zum potenziellen Performance-Vorteil für die Laufzeit deines Programms, je nachdem wie geeignet die Elemente sind, die dein Programm verarbeitet. |
||||||
|
Ehemalige
Anmeldungsdatum: Beiträge: 4784 Wohnort: Berlin |
@UlfZibis: Von dem ”Optimierer” solltest Du nichts erwarten. Im Grunde gibt es da nichts was über einfaches „constant folding“ hinaus geht. Und selbst das wird noch nicht besonders lange gemacht. Der Rückgabetyp ist aber schon aus der Dokumentation von |