Iteration logic can be expressed with imperative loops. But a shared library of code is simpler to maintain. We find these functions in the itertools
module.
With itertools
, we can express iteration in a more elegant way. This is declarative code as opposed to imperative code. Even complex things like permutations can be done.
This method generates an infinitely repeating series of values. It receives an iterable
collection. And it endlessly repeats those elements, in a cycle.
cycle()
. We then loop over the first ten elements of the result, which are 1, 2 and 3 repeated.cycle()
, as by passing it to the list()
built-in, your program will freeze.import itertools # Cycle through these values. result = itertools.cycle([1, 2, 3]) # Display first ten results. i = 0 for value in result: print(value) i += 1 if i >= 10: break1 2 3 1 2 3 1 2 3 1
Count
With count()
we generate a count. We specify the start value (here it is zero) and then advance by a step. But using the default step of 1 is more common.
import itertools # Generate count from 0 to infinity, with step of 2. result = itertools.count(0, 2) # Display until value 10. for value in result: print(value) if value >= 10: break0 2 4 6 8 10
Repeat()
receives 2 arguments. The first argument is the value you want to repeat. And the second argument is the number of times you wish to repeat that value.
import itertools # Repeat the value 5 four times. result = itertools.repeat(5, 4) print(list(result))[5, 5, 5, 5]
This program uses takewhile. With takewhile, we continue "taking" elements from the start until one does not match the predicate condition.
import itertools # A list with seven values. values = [1, 5, 6, 8, 10, 12, 1] # Take values until one is higher than 9. result = itertools.takewhile(lambda v: v < 10, values) for value in result: print(value)1 5 6 8
Dropwhile()
eliminates elements at the start of an iterable
. The predicate lambda is evaluated—while it evaluates to true, elements are removed.
dropwhile()
returns the remaining elements as an iterator.import itertools values = ["cat", "dog", "turnip", "carrot", "fish"] # Drop values while they are less than length 3. result = itertools.dropwhile(lambda s: len(s) <= 3, values) for value in result: print(value)turnip carrot fish
A permutation treats differently-ordered values as a separate result. It generates all possible sequences within an argument.
permutations()
method an iterable
argument. The second argument is the desired length of the results.import itertools values = [1, 2, 3] # Get all permutations of the three numbers. result = itertools.permutations(values, 2) for value in result: print(value)(1, 2) (1, 3) (2, 1) (2, 3) (3, 1) (3, 2)
Chain combines many iterable
collections into a single one. Here we pass chain()
3 lists, and it returns one sequence of those values. Lists are not required.
Chain()
can accept any number of arguments. Three lists are accepted, but so are fewer or more.import itertools values1 = [1, 2, 3, 4] values2 = [5, 6, 7, 8] values3 = [9, 10] # Chain three lists into one iterable. result = itertools.chain(values1, values2, values3) print(list(result))[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
With filterfalse, we specify a predicate, often a lambda expression. Elements where the predicate evaluates to true are removed by filterfalse.
import itertools values = ["cat", "parrot", "dog", "bird"] # Filter out values with length greater than or equal to 4. result = itertools.filterfalse(lambda e: len(e) >= 4, values) for element in result: print(element)cat dog
With itertools
we write programs in a more functional way. We can specify what we want, and have itertools
do the looping and processing—this is sometimes an improvement.
Itertools functions are powerful, and we do not need to write them for each program. Instead we can use these functions in many programs.