Generators/Iterators

A place where you can post Python-related tutorials you made yourself, or links to tutorials made by others.

Generators/Iterators

Postby micseydel » Fri Feb 22, 2013 2:04 am

Iterators a simple objects which can be iterated over, and which can be interrupted, and continued later one. If you have an iterable such as a list, string, set, tuple, etc., you can produce an iterator from them with the built-in iter() keyword.
Code: Select all
>>> string = "hello there i am a string"
>>> iter_string = iter(string)
>>> for char in iter_string:
   if char != ' ':
      print char,
   else:
      break

   
h e l l o
>>> for char in iter_string:
   if char != ' ':
      print char.upper(),
   else:
      break

   
T H E R E
>>> print ''.join(iter_string)
i am a string

File objects are a special case iterator which iterates over the lines of the file. File objects are more powerful than the iterators returned by iter() however because you can rewind them. An iterator in generator may be rewound or reset, however those return by iter() are not. If you want to use a while loop on an iterator, you get the next item with the built-in next() method and you must catch a StopIteration once the iterator is exhausted.

Generators are a way of generating values (usually for a loop) without creating those values in advance. It can be said that iterators are a special case of generators. Where an iterator iterates over something which exists in memory already, generators produce their values "on the fly". Generators look much like functions except instead of return they use yield, for example
Code: Select all
>>> from itertools import count # xrange with no upper limit
>>> def squares_gen(start=2):
   for x in count(start):
      yield x**2

      
>>> squares = squares_gen()
>>> for square in squares:
   if square > 100:
      break
   print square

   
4
9
16
25
36
49
64
81
100

When yield is used, execution of the generator is suspended, and is resumed when next() is called on it (which happen implicitly in a for loop). I wrote this such that it is an infinite generator, however you could specific an upper bound as a parameter as well.

Generator tricks
Code: Select all
>>> def take_pairs(iterable):
   it = iter(iterable)
   return zip(it, it)

>>> take_pairs([1, 2, 3, 4, 5, 6])
[(1, 2), (3, 4), (5, 6)]

Questions and comments welcome as always, and I'll leave it up to the community to come up with more generator tricks.
Join the #python-forum IRC channel on irc.freenode.net!

Please do not PM members regarding questions which are meant to be discussed publicly. The point of the forum is so that others can benefit from it. We don't want to help you over PMs or emails.
User avatar
micseydel
 
Posts: 1223
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Return to Tutorials

Who is online

Users browsing this forum: No registered users and 3 guests