System Development with Python

Week 3 :: iterators and generators

Exceptions aren't just for errors

Exception handling can be used for control flow as well

i.e. StopIteration for iterators

Iterators

Iterators are objects which support a concept of iteration over a collection

# looping over the lines in a file is done via an iterator:
  with open("file.dat") as f:
      for line in f:
          print line

  # and you can create your own
  for x in foo():
      print x

An iterable is an object which follows the Python iterator protocol

An iterator defines two required methods in order to iterate

http://docs.python.org/2/library/stdtypes.html#iterator-types

Demonstration iterator

class CountToTen(object):
      """an iterator which returns integers from 0 to 9, inclusive"""

      def __init__(self):
          self.data = range(10)

      def __iter__(self):
          return self

      def next(self):
          try:
              return self.data.pop(0)
          except IndexError:
              raise StopIteration

  for x in CountToTen():
      print x

  # or consume the whole thing at once by converting to a list:
  list(CountToTen())
  

Now let's build an iterator

Look at the stubbed code in /examples/week-03-debugging/fib_exercise.py

Modify the run() function so it is a real iterable

The Fibonnaci sequence is defined as such:

Where do we use iterators and why?

Iterating over resource-intensive types

Examples in the wild:

Exercise

Look at the code in /examples/week-3/iterators/yrange.py

Exercise

Write a Take iterable that does the following:

generators

A generator is a concrete type that implements the iterator protocol.

Convert a function to a generator using the yield keyword

def count_to_10():
    for i in range(10):
        yield i

for x in count_to_10():
    print x
      

(4700 upvotes on this stackoverflow question, yield is confusing at first)

http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained

Using a generator expression to create a generator

Python list comprehensions allow you to build lists of values

my_list = [x for x in open('file.dat')]

Convert that list comprehension to a generator just by replacing '[]' with '()'

my_generator = (x for x in open('file.dat'))
https://wiki.python.org/moin/Generators

Questions?

/