List Comprehension richtig verstehen

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.
stefanbunde
User
Beiträge: 29
Registriert: Dienstag 20. Oktober 2015, 12:59

die LC gibt dir ja eine liste mit elementen zurück.
und der erste wert dort gibt an, wie die elemente aussehen sollen.
in deinem fall wird einfach nur b zurück gegeben

Code: Alles auswählen

attribut = [b * b for b in list1 if b]
dieses beispiel würde eine liste mit den quadratzahlen von b zurückgeben, sofern b weder 0 noch None oder False ist
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo pillmuncher und Stefanbunde,

wenn ich es also richtig verstehe, dann dient der Ausdruck (b) für die neue Liste, die vom LC erzeugt wurde? Das heißt, all die neuen Elemente werden über diesen Ausdruck (b) in die neue Liste hinzugefügt? Im Umkehrschluss: Würde ich rein hypothetisch diesen Ausdruck weglassen, hätte die LC keine Möglichkeit eine neue Liste mit neuen Elementen zu erstellen, da der Ausdruck fehlt?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Sophus: Um es umgangssprachlich auszudrücken: das erste 'b' in der LC ist das, "was in die Liste kommt" - das, was sonst in einer for-Loop per append hinzugefügt würde.
Zuletzt geändert von kbr am Donnerstag 29. Oktober 2015, 13:16, insgesamt 1-mal geändert.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Danke dir, kbr. Jetzt geht ein Licht bei mir auf.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Oder nochmal anders geschrieben:
[Tätigkeit-mit-Element for Element in Quell-Liste]

Und alternativ mit einer Bedingung als Zusatz:
[Tätigkeit-mit-Element for Element in Quell-Liste if Bedingung-für-Element]

Bei der zweiten Form landen nur die Elemente im Ergebnis, für welche die Bedingung zutrifft. Das ist also ein Filter, um das Ergebnis einzuschränken.

Tätigkeit-mit-Element kann auch das Element selbst sein, ohne dass damit eine Operation ausgeführt wird. Das kann sinnvoll sein, wnen man ein if im Ausdruck hat. Also in dieser Art:

Code: Alles auswählen

[elem for elem in mylist if elem.startswith('x')]
EDIT: Und mit "Quell-Liste" ist allgemein ein iterierbares Objekt gemeint, wie z.B. auch ein Tupel oder ein String. Ich wollte es sprachlich hier etwas einfacher halten, weil der Fragesteller da meiner Meinung nach mehr von hat.
Zuletzt geändert von snafu am Donnerstag 29. Oktober 2015, 14:23, insgesamt 1-mal geändert.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sophus hat geschrieben:Wenn ich mir folgende LC anschaue:

Code: Alles auswählen

attribut = [b for b in list1 if b]
Verstehe ich den For/In-Bereich (for b in list1) und den If-Statement (if b). Und ich weiß auch, dass das erste b ein Ausdruck ist, mit dem die LC immer beginnt. Was macht das erste b in diesem Fall? Es ist schon mal nicht im For/In-Bereich, also iteriert wird dieser Ausdruck nicht, und in der Bedingung ist er auch nicht mit eingebunden. Und ich glaube auch nicht, dass das erste b nur als Dekoration dient.
Wie bereits geschrieben (und vielleicht auch inzwischen von dir erkannt): Das erste `b` ist das, was in das Ergebnis der List Comprehension - d.h. in die neue Liste - kommt. Man muss das nochmal gesondert hinschreiben, weil `b` eigentlich `Operation-auf-b` meint. Das kann z.B. auch `b * b` sein oder `b * 2 / x`. Dann landet eben das Resultat dieser Berechnung als jeweiliges Element im Ergebnis der LC.
Sophus hat geschrieben:Im Umkehrschluss: Würde ich rein hypothetisch diesen Ausdruck weglassen, hätte die LC keine Möglichkeit eine neue Liste mit neuen Elementen zu erstellen, da der Ausdruck fehlt?
Das ist richtig.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ich verweise nochmal auf die "Langform" in meinem ersten Post hier ;)

Hier mal ein Beispiel in dem gar kein `b` mehr als erster Ausdruck vorkommt:

Code: Alles auswählen

penguin_count = sum(1 for animal in animals if animal == "penguin")
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

cofi hat geschrieben:

Code: Alles auswählen

penguin_count = sum(1 for animal in animals if animal == "penguin")
Schönes Beispiel. Und die 1 kriegen wir auch noch weg:

Code: Alles auswählen

penguin_count = sum(animal == "penguin" for animal in animals)
Wobei beides keine LCs sind, sondern Generator Expressions.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ja, aber dann ist wieder das "b" im ersten Ausdruck ;)
So ganz geeignet war das Beispiel dann doch nicht :roll:
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Leute Leute, ich weiß ja die Pinguine sehr zu schätzen. Die Tiere sind ja unheimlich süß.

Aber wenn der Ausdruck b wegfällt, was hat dann die Zahl 1 für eine Funktion? Ich bin wieder verwirrt. :shock:
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ich hatte mir ja schon sowas gedacht, darum das Beispiel.
Der erste Ausdruck (hier eben 1) ist das was in der Liste landet, das muss mit der Ausgangsliste nichts zu tun haben.
In dem Fall wird also eine Liste mit genauso vielen 1en erstellt wie "pinguin" in `animals` vorkommt.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Ok. Jetzt leuchtet es wieder ein. Ich bin da noch nicht so standfest. Da können mich schon ein paar Pinguine schnell verwirren. 8)
Antworten