|
593 | 593 | \gitPythonAndOutput{\programmingWithPythonCodeRepo}{07_iteration}{generator_expressions_to_collection.py}{--args format}{iteration:generator_expressions_to_collection}{%
|
594 | 594 | Using generator expressions when creating collection datastructures\pythonIdx{Generator}\pythonIdx{list}\pythonIdx{dict}.}%
|
595 | 595 | %
|
596 |
| -\FloatBarrier% |
597 |
| -% |
598 | 596 | \begin{sloppypar}%
|
599 | 597 | Finally, generator expressions can also be passed to the constructors of collection datastructures or other functions that create such datastructures.
|
600 | 598 | In \cref{lst:iteration:generator_expressions_to_collection}, we first define a string \pythonil{csv_text} with the value~\pythonil{"22,56,33,67,43,33,12"}.
|
|
701 | 699 | \FloatBarrier%
|
702 | 700 | \endhsection%
|
703 | 701 | %
|
| 702 | +\hsection{Operations on Iterators}% |
| 703 | +% |
| 704 | +\gitPythonAndOutput{\programmingWithPythonCodeRepo}{07_iteration}{filter_takewhile.py}{--args format}{iteration:filter_takewhile}{% |
| 705 | +An example for \pythonilIdx{takewhile}\pythonIdx{itertools!takewhile} and \pythonilIdx{filter}.}% |
| 706 | +% |
| 707 | +Sequences play a very important role in \python\ programming. |
| 708 | +The fact that generator functions and the \pythonilIdx{yield} keyword were added to the language just to provide a natural way to construct complex sequences speaks for itself~\cite{PEP255}. |
| 709 | +Naturally, there also are several utilities for working with and transforming sequences. |
| 710 | +Some of these tools are directly provided as built-in functions, some ship with the module~\pythonilIdx{itertools}~\cite{PSF2024IFCIFEL}. |
| 711 | +Here we want to discuss a few of them. |
| 712 | + |
| 713 | +The first two tools we will look at are the built-in function \pythonilIdx{filter} and the \pythonilIdx{takewhile}\pythonIdx{itertools!takewhile} function from the \pythonilIdx{itertools} module. |
| 714 | +In the previous section, we implemented a generator function returning the endless sequence of prime numbers in \cref{lst:loops:for_loop_sequence_primes}. |
| 715 | +What would we do if we wanted a convenient way to create a list of all prime numbers which are less than 50 by using this never-ending generator? |
| 716 | +The answer can be found in \cref{lst:iteration:filter_takewhile}. |
| 717 | + |
| 718 | +\pythonilIdx{takewhile} is a function with two parameters: |
| 719 | +The second parameter is an \pythonilIdx{Iterator}. |
| 720 | +Let's say that it provides a sequence of elements of some type~\pythonil{T}. |
| 721 | +The first parameter then is a predicate, which is a function accepting one element of type~\pythonil{T} and returning a \pythonil{bool} value. |
| 722 | +Back in \cref{sec:functionsAsVarsAndLambdas}, we learned that we can also pass functions or \pythonilsIdx{lambda} as arguments to other functions. |
| 723 | +This is a practical example of that. |
| 724 | +Basically, \pythonilIdx{takewhile} constructs a new \pythonilIdx{Iterator} which returns the elements from the original \pythonilIdx{Iterator} as long as the predicate function returns~\pythonil{True} for them. |
| 725 | +As soon as the predicate returns \pythonil{False}, it will stop the iteration. |
| 726 | +Therefore, the answer to \inQuotes{How can I extract all the numbers less than~50 from the prime sequence?} is simply to call \pythonil{akewhile(lambda z: z < 50, primes())}. |
| 727 | +This sequence is now no longer infinitely long and can conveniently be converted to a \pythonil{list}. |
| 728 | + |
| 729 | +The built-in function~\pythonilIdx{filter} works quite similarly. |
| 730 | +It, too, accepts a predicate and an~\pythonilIdx{Iterator} as input. |
| 731 | +Different from \pythonil{takewhile}, the new \pythonilIdx{Iterator} created by \pythonilIdx{filter} does not stop if the predicate returns~\pythonil{False}. |
| 732 | +However, it only returns only those elements for which the predicate returned~\pythonil{True}. |
| 733 | +In \cref{lst:iteration:filter_takewhile}, we use this to select prime numbers~$x$ for which an integer~$y$ exists such that~$x=y^2+1$. |
| 734 | +This time, we implement the predicate as function \pythonil{sqr_plus_1} and pass this function to \pythonilIdx{filter}. |
| 735 | +Since there again probably infinitely many such prime numbers, we return only those that are less than~1000, for which we use~\pythonil{takewhile}. |
| 736 | +The results can be seen in \cref{exec:iteration:filter_takewhile}. |
| 737 | +\FloatBarrier% |
| 738 | +\endhsection% |
| 739 | +% |
704 | 740 | \endhsection%
|
705 | 741 | %
|
0 commit comments