Tutorial by Examples

A generator object supports the iterator protocol. That is, it provides a next() method (__next__() in Python 3.x), which is used to step through its execution, and its __iter__ method returns itself. This means that a generator can be used in any language construct which supports generic iterable o...
The next() built-in is a convenient wrapper which can be used to receive a value from any iterator (including a generator iterator) and to provide a default value in case the iterator is exhausted. def nums(): yield 1 yield 2 yield 3 generator = nums() next(generator, None) # 1 ...
In addition to receiving values from a generator, it is possible to send an object to a generator using the send() method. def accumulator(): total = 0 value = None while True: # receive sent value value = yield total if value is None: break # aggr...
It's possible to create generator iterators using a comprehension-like syntax. generator = (i * 2 for i in range(3)) next(generator) # 0 next(generator) # 2 next(generator) # 4 next(generator) # raises StopIteration If a function doesn't necessarily need to be passed a list, you can sa...
Generator expressions are similar to list, dictionary and set comprehensions, but are enclosed with parentheses. The parentheses do not have to be present when they are used as the sole argument for a function call. expression = (x**2 for x in range(10)) This example generates the 10 first perfe...
A practical use case of a generator is to iterate through values of an infinite series. Here's an example of finding the first ten terms of the Fibonacci Sequence. def fib(a=0, b=1): """Generator that yields Fibonacci numbers. `a` and `b` are the seed values""" ...
Generators can be used to represent infinite sequences: def integers_starting_from(n): while True: yield n n += 1 natural_numbers = integers_starting_from(1) Infinite sequence of numbers as above can also be generated with the help of itertools.count. The above code cou...
Python 3.x3.3 Use yield from if you want to yield all values from another iterable: def foob(x): yield from range(x * 2) yield from range(2) list(foob(5)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1] This works with generators as well. def fibto(n): a, b = 1, 1 while True: ...
Generators can be used to implement coroutines: # create and advance generator to the first yield def coroutine(func): def start(*args,**kwargs): cr = func(*args,**kwargs) next(cr) return cr return start # example coroutine @coroutine def adder(sum = 0): ...
First, import the libraries that work with files: from os import listdir from os.path import isfile, join, exists A helper function to read only files from a directory: def get_files(path): for file in listdir(path): full_path = join(path, file) if isfile(full_path): ...
To iterate over several generators in parallel, use the zip builtin: for x, y in zip(a,b): print(x,y) Results in: 1 x 2 y 3 z In python 2 you should use itertools.izip instead. Here we can also see that the all the zip functions yield tuples. Note that zip will stop iterating as soon...
Suppose you have complex code that creates and returns a list by starting with a blank list and repeatedly appending to it: def create(): result = [] # logic here... result.append(value) # possibly in several places # more logic... return result # possibly in several places...
The next function is useful even without iterating. Passing a generator expression to next is a quick way to search for the first occurrence of an element matching some predicate. Procedural code like def find_and_transform(sequence, predicate, func): for element in sequence: if predi...

Page 1 of 1