From b8b2f2a4790a16490f25b4643c7ed57c40d9e5d8 Mon Sep 17 00:00:00 2001 From: Eric Wolf Date: Fri, 15 Oct 2021 22:33:57 +0200 Subject: [PATCH 1/2] add generator example This addresses issue #18 and adds correct syntax. --- latex/slides/06_comprehensions.tex | 8 +++-- .../resources/06_comprehensions/generators.py | 14 +++++++++ md/06_comprehensions.md | 31 +++++++++++++++++-- 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 latex/slides/resources/06_comprehensions/generators.py diff --git a/latex/slides/06_comprehensions.tex b/latex/slides/06_comprehensions.tex index 51531ad..e0cb20a 100644 --- a/latex/slides/06_comprehensions.tex +++ b/latex/slides/06_comprehensions.tex @@ -62,16 +62,18 @@ \section{Generators} \begin{description} \item[Generator] Ein Objekt, \"uber das iteriert werden kann. Wenn ein Element daraus verwendet wurde, ist es nicht mehr in dem Generatorobjekt enthalten.\\[.5cm] \end{description} - - Die grundlegende Syntax ist gleich der einer \textit{List Comprehension}. + Grundlegender Syntax: \alert{\texttt{( EXPRESSION for LAUFVARIABLE in ITERABLE (if FILTER) )}}\\ Da sich \alert{\texttt{list}} und \alert{\texttt{dict}} auch aus Iterables bauen lassen, gilt prinzipiell:\\[.25cm] \alert{\texttt{list(EXPRESSION for VARIABLE in ITERABLE) == [EXPRESSION for VARIABLE in ITERABLE]}}\\[.25cm] und\\[.25cm] \alert{\texttt{dict((KEY, VALUE) for VARIABLE in ITERABLE) == \{KEY:VALUE for VARIABLE in ITERABLE\}}}\\[.25cm] - \textbf{Aber:} Generators verhalten sich anders als Lists oder Dicts! + \textbf{Aber:} Generatoren sind lazy, sie erzeugen die Elemente erst wenn sie iteriert werden. +\end{frame} +\begin{frame}{Generators - Beispiel} + \lstinputlisting{resources/06_comprehensions/generators.py} \end{frame} diff --git a/latex/slides/resources/06_comprehensions/generators.py b/latex/slides/resources/06_comprehensions/generators.py new file mode 100644 index 0000000..76a0bf7 --- /dev/null +++ b/latex/slides/resources/06_comprehensions/generators.py @@ -0,0 +1,14 @@ +# liefert gerade Zahlen von 0 bis 10 (10 nicht enthalten) +generator = (i for i in range(10) if i % 2 == 0) + +# gibt 0, 2, 4, 6 und 8 aus +for number in generator: + print(number) + +# gibt nichts aus, generator ist erschöpft +for number in generator: + print(number) + +# wenn alle Elemente sofort erzeugt werden würde mindestens 4GB Speicher benötigt +for number in (i for i in range(2**32)): + print(number) diff --git a/md/06_comprehensions.md b/md/06_comprehensions.md index 9c4c83e..f3ef6c9 100644 --- a/md/06_comprehensions.md +++ b/md/06_comprehensions.md @@ -78,6 +78,7 @@ Grundlegender Syntax: Fast der gleiche Syntax, nur diesmal mit 2 Expressions: __KEY__ und __VALUE__. Ansonsten gelten die gleichen Regeln. +--- ## Beispiel @@ -99,8 +100,13 @@ enthalten. --- -Die grundlegende Syntax ist gleich der einer *List Comprehension*. Da -sich `list` und `dict` auch aus Iterables bauen lassen, gilt prinzipiell: +Grundlegender Syntax: + +```python +(EXPRESSION for LAUFVARIABLE in ITERABLE (if FILTER)) +``` + +Da sich `list` und `dict` auch aus Iterables bauen lassen, gilt prinzipiell: ```python list(EXPR for VAR in ITERABLE) == [EXPR for VAR in ITERABLE] @@ -110,6 +116,25 @@ und dict((KEY, VAL) for VAR in ITERABLE) == {KEY: VAL for VAR in ITERABLE} ``` +**Aber:** Generatoren sind lazy, sie erzeugen die Elemente erst wenn sie iteriert werden. + --- -**Aber:** Generators verhalten sich anders als Lists oder Dicts! +## Beispiel + +```python +# liefert gerade Zahlen von 0 bis 10 (10 nicht enthalten) +generator = (i for i in range(10) if i % 2 == 0) + +# gibt 0, 2, 4, 6 und 8 aus +for number in generator: + print(number) + +# gibt nichts aus, generator ist erschöpft +for number in generator: + print(number) + +# wenn alle Elemente sofort erzeugt werden würde mindestens 4GB Speicher benötigt +for number in (i for i in range(2**32)): + print(number) +``` From 6e676415c3c5c0c3270be347090be509e25a28fb Mon Sep 17 00:00:00 2001 From: Eric Wolf Date: Fri, 15 Oct 2021 23:27:26 +0200 Subject: [PATCH 2/2] add nesting to comprehensions This should close issue #18 --- latex/slides/06_comprehensions.tex | 11 ++++++ .../resources/06_comprehensions/nesting.py | 22 +++++++++++ md/06_comprehensions.md | 39 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 latex/slides/resources/06_comprehensions/nesting.py diff --git a/latex/slides/06_comprehensions.tex b/latex/slides/06_comprehensions.tex index e0cb20a..7d07db2 100644 --- a/latex/slides/06_comprehensions.tex +++ b/latex/slides/06_comprehensions.tex @@ -76,6 +76,17 @@ \section{Generators} \lstinputlisting{resources/06_comprehensions/generators.py} \end{frame} +\section{Nesting} +\begin{frame}{Nesting} + \alert{\texttt{for}} Schleifen in Comprehensions können verschachtelt werden. + Dabei werden sie von Links nach Rechts ausgeführt, was man bei Variablen beachten muss. + + \textbf{Wichtig:} Starke Verschachtelung verringert die Lesbarkeit! +\end{frame} + +\begin{frame}{Nesting - Beispiel} + \lstinputlisting{resources/06_comprehensions/nesting.py} +\end{frame} %\section{Misc} %\begin{frame}{Misc} diff --git a/latex/slides/resources/06_comprehensions/nesting.py b/latex/slides/resources/06_comprehensions/nesting.py new file mode 100644 index 0000000..411ac27 --- /dev/null +++ b/latex/slides/resources/06_comprehensions/nesting.py @@ -0,0 +1,22 @@ +# erzeugt eine Liste welche jede Zahl n +# von 0 bis 4 (4 nicht enthalten) n mal enthält +list1 = [i for i in range(4) for _ in range(i)] + +# gleicher Code ohne Comprehension +list2 = [] +for i in range(4): + for _ in range(i): + l.append(i) + +list1 == list2 == [1,2,2,3,3,3] + +# löst einen NameError aus, weil +# a erst durch die zweite Schleife entsteht +[i for i in range(a) for a in range(i)] + +# zählt für jede Zahl n von 0 bis 4 (4 nicht enthalten) +# von 0 bis n-1, weil EXPRESSION erst nach der letzten +# Schleife evaluiert wird +list3 = [a for i in range(4) for a in range(i)] + +list3 == [0,0,1,0,1,2] diff --git a/md/06_comprehensions.md b/md/06_comprehensions.md index f3ef6c9..55cabdd 100644 --- a/md/06_comprehensions.md +++ b/md/06_comprehensions.md @@ -138,3 +138,42 @@ for number in generator: for number in (i for i in range(2**32)): print(number) ``` + + +# Nesting + +## Nesting + +`for` Schleifen in Comprehensions können verschachtelt werden. +Dabei werden sie von Links nach Rechts ausgeführt, was man bei Variablen beachten muss. + +**Wichtig:** Starke Verschachtelung verringert die Lesbarkeit! + +--- + +## Beispiel + +```python +# erzeugt eine Liste welche jede Zahl n +# von 0 bis 4 (4 nicht enthalten) n mal enthält +list1 = [i for i in range(4) for _ in range(i)] + +# gleicher Code ohne Comprehension +list2 = [] +for i in range(4): + for _ in range(i): + l.append(i) + +list1 == list2 == [1,2,2,3,3,3] + +# löst einen NameError aus, weil +# a erst durch die zweiten Schleife entsteht +[i for i in range(a) for a in range(i)] + +# zählt für jede Zahl n von 0 bis 4 (4 nicht enthalten) +# von 0 bis n-1, weil EXPRESSION erst nach der letzten +# Schleife evaluiert wird +list3 = [a for i in range(4) for a in range(i)] + +list3 == [0,0,1,0,1,2] +```