<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>learning python &#187; Iterators</title>
	<atom:link href="http://www.learningpython.com/tag/iterators/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.learningpython.com</link>
	<description>one man's journey into python...</description>
	<lastBuildDate>Mon, 26 Apr 2010 01:21:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Iterators, Iterables, and Generators! Oh, my!</title>
		<link>http://www.learningpython.com/2009/02/23/iterators-iterables-and-generators-oh-my/</link>
		<comments>http://www.learningpython.com/2009/02/23/iterators-iterables-and-generators-oh-my/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 13:32:52 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[Python Magazine]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Generators]]></category>
		<category><![CDATA[Iterables]]></category>
		<category><![CDATA[Iterators]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=110</guid>
		<description><![CDATA[
			
				
			
		
By: Mark Mruss
Note: This article was first published the January 2008 issue of Python Magazine
Iterators, iterables, and generators are features handled so wall by Python that people programming in other languages cannot help but drool over. Fortunately for us, creating iterators, iterables and generators is a relatively simple task. This article introduces the concepts of [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2009%2F02%2F23%2Fiterators-iterables-and-generators-oh-my%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2009%2F02%2F23%2Fiterators-iterables-and-generators-oh-my%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>By: Mark Mruss</strong></p>
<p><strong>Note:</strong> This article was first published the <a href="http://www.pythonmagazine.com/c/issue/view/66">January 2008 issue</a> of <a href="http://www.pythonmagazine.com">Python Magazine</a></p>
<p>Iterators, iterables, and generators are features handled so wall by Python that people programming in other languages cannot help but drool over. Fortunately for us, creating iterators, iterables and generators is a relatively simple task. This article introduces the concepts of iterators, iterables, and generators and illustrates how easy it is to add them to your code.</p>
<ol>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#IterationInPython">Iteration in Python</a></li>
<li><a href="#AnInitialExample">An Initial Example</a></li>
<li><a href="#CreatingAnIterator">Creating An Iterator</a></li>
<li><a href="#LookingMoreCloselyAtTheIterator">Looking More Closely At The Iterator</a></li>
<li><a href="#TheUpsideAndDownsideOfIterators">The Upside And Downside Of Iterators</a></li>
<li><a href="#Generators">Generators</a></li>
<li><a href="#LookingCloselyAtTheGenerator">Looking Closely At The Generator</a></li>
<li><a href="#ButWhatAboutIterables">But What About Iterables?</a></li>
<li><a href="#CreatingAnIterableObject">Creating An Iterable Object</a></li>
<li><a href="#Conclusion">Conclusion</a></li>
</ol>
<p><span id="more-110"></span></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>In this article I&#8217;m going to introduce three related Python features: iterators, iterables, and generators. Generators are easy to define, they are functions that create and return an iterator. Iterators and iterables on the other hand, are easier to use than they are to define. An iterable object is a &#8220;container object capable of returning its members one at a time.&#8221;[1] An iterator object is &#8220;An object representing a stream of data. Repeated calls to the iterator&#8217;s next() method return successive items in the stream. When no more data is available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its next() method just raise StopIteration again.&#8221;<a href="#1">[1]</a> You can think of the difference between the two in this way: an iterable object can be iterated over multiple times, whereas an iterator object can only be iterated over once. In general an iterable produces an iterator every time something wants to iterate over its data. </p>
<p><strong>Note:</strong> Classes that define the <code>__getitem__</code> function are also considered iterables, but since that falls outside the scope of this article, it will not be covered here.</p>
<p>In this tutorial, I will begin by discussing iterators, the most basic concept. Then I will move onto generators, and finish by discussing iterables, the most wide open topic of the three.</p>
<h2><a name="IterationInPython">Iteration in Python</a></h2>
<p>Iterators objects are used in Python in order to iterate over an objects data. For example, we all know how to do this in Python when we work with lists:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_list</span><span class="hl-default"> = </span><span class="hl-brackets">[</span><span class="hl-number">1</span><span class="hl-code">,</span><span class="hl-number">2</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-brackets">]
</span><span class="hl-reserved">for </span><span class="hl-identifier">num </span><span class="hl-reserved">in </span><span class="hl-identifier">my_list</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-identifier">num</span></pre></div></div>
<p>This code will iterate over the list object <code>my_list</code> and print out all of the list items , i.e., the numbers 1, 2, and 3. Iterating over sequences in this simple and transparent manner happens to be one of my favourite features of Python. </p>
<p>According to our definition above, lists are iterables since you can iterate over them multiple times. In fact, each time you iterate over a list you are actually using a listiterator iterator object produced by the list.</p>
<p>It may not be immediately clear to you when you should add an iteration support to a class. However, the more you work with Python the more you&#8217;ll find instances when doing just this is very useful, sometimes the only advantage is cleaner looking code. One nice thing about iterators (and generators too) is that the processing for each item happens as you need it.  Instead of collecting all of the data into a list and then running through the list, you will collect each item as you need it. This might not seem like a large difference but imagine if there were tens of thousands of items to process? What if you were collection your data from an online source? Performing all of your processing up front may take a very long time, especially if you only wanted the first few items.</p>
<h2><a name="AnInitialExample">An initial example</a></h2>
<p>In order to explain iteration further, let&#8217;s look at a simple example task where we might use iterators. For this example we will create a class that takes a string of characters as input and then converts each character into its byte value.  If we were <strong>NOT</strong> going to use iterators we might do something like what is found in Listing 1.</p>
<p><strong>Listing 1</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">data</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default"> = </span><span class="hl-identifier">data

	</span><span class="hl-reserved">def </span><span class="hl-identifier">to_bytes</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">bytes</span><span class="hl-default"> = </span><span class="hl-brackets">[]
		</span><span class="hl-reserved">for </span><span class="hl-identifier">char </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default">:
			</span><span class="hl-identifier">bytes</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">char</span><span class="hl-brackets">))
		</span><span class="hl-reserved">return </span><span class="hl-identifier">bytes</span></pre></div></div>
<p>This code is pretty simple. We have a data member, named <code>data</code>, that we use to store the string that was used to initialize the class. In the <code>to_bytes</code> function we loop through the string, converting each character to its byte value using the built in <code>ord</code> function. We store each byte value in a list and once we have collected all of the values we return that list.</p>
<p>When we run the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">for </span><span class="hl-identifier">byte </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">to_bytes</span><span class="hl-brackets">()</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-identifier">byte</span></pre></div></div>
<p>we would get this as our output:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-number">97
98
99
100
101
102</span></pre></div></div>
<h2><a name="CreatingAnIterator">Creating an Iterator</a></h2>
<p>Let&#8217;s convert this into an iterator. Making your class into an iterator requires adding &#8220;two methods, which together form the iterator protocol.&#8221;<a href="#2">[2]</a> The two functions needed are: 1) the <code>__iter__</code> function; and, 2) the <code>next</code> function. The <code>__iter__</code> function will return the object itself, while the <code>next</code> function will return the next item. The <code>next</code> function is where the actual iteration work occurs. The <code>next</code> function iterates by returning the next item in the &#8220;sequence&#8221; each time it is called for as long as there is a &#8220;next&#8221; item.  When there are no more items to iterate over, the <code>next</code> function must raise the <code>StopIteration</code> exception to halt the iteration.</p>
<p>To be clear, in order to make your class an iterator you need to do two things:</p>
<p><strong>1)</strong> Add an <code>__iter__</code> function that returns the object itself (<code>self</code>)</p>
<p><strong>2)</strong> Add a <code>next</code> function that returns the next item in the sequence each time it is called. When there are no more items in the sequence, the <code>next</code> function raises a <code>StopIteration</code> exception signal the end of the iteration. </p>
<p>For those of you still confused, the following example will help illustrate how iterators work. If we were to convert our ByteValue class into an iterator object, it might look something like Listing 2.</p>
<p><strong>Listing 2</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">data</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default"> = </span><span class="hl-identifier">data
		self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-number">0

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__iter__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self

	</span><span class="hl-reserved">def </span><span class="hl-identifier">next</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-code"> == </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-reserved">raise StopIteration
		else</span><span class="hl-default">:
			</span><span class="hl-identifier">byte_value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> += </span><span class="hl-number">1
			</span><span class="hl-reserved">return </span><span class="hl-identifier">byte_value</span></pre></div></div>
<p>Let&#8217;s compare the code in Listings 1 and Listing 2 in detail, focusing on the iterator in Listing 2.  The first difference is the addition of the data member <code>current_item</code> to the class, initialized in the <code>__init__</code> function.  <code>current_item</code> serves as a counter and keeps track of the current character in the string while we iterate over it.  The counter must have class scope since the iterator works through successive calls to the <code>next</code> function.  If <code>current_item</code> were local to the <code>next</code> function, its value would be reset with each subsequent call, and would not be of much use.</p>
<p>The second difference between the listings is the addition in Listing 2, of the <code>__iter__</code> function where we return <code>self</code>.</p>
<p>The final addition to Listing 2 is the <code>next</code> function, where we first check to see if <code>current_item</code> is equal to the length of our string.  If <code>current_item</code> is equal to the strings length we raise the <code>StopIteration</code> exception to signal the end of the iteration because we have no more characters left to iterate over. If there are more characters to iterate over we calculate the byte value of the current character, increase our <code>current_item</code> counter, and then return the byte value.</p>
<p><strong>Note:</strong> Notice that <code>current_item</code> is only initialized when the ByteValue object is created. This happens because according to the iteration protocol, &#8220;once an iterator&#8217;s next() method raises StopIteration, it will continue to do so on subsequent calls.&#8221;<a href="#2">[2]</a> If we were to re-initialize <code>current_item</code> we would then be able to iterate over the iterator more than once breaking the iteration protocol.</p>
<p>Now that we have converted our class into an iterator we can use it as follows:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">for </span><span class="hl-identifier">byte </span><span class="hl-reserved">in </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-identifier">byte</span></pre></div></div>
<p>Doing so would result in:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-number">97
98
99
100
101
102</span></pre></div></div>
<p>Notice that we do not store the instance of our ByteValue class in a variable. Doing so would be useless because since ByteValue is an iterator it is only good for one pass of the data. If ByteValue were an iterable (returning an iterator object when <code>__iter__</code> was called) it would make sense to keep an instance around because we could iterate over the instance more than once. We will look at creating iterables later on in this article. </p>
<h2><a name="LookingMoreCloselyAtTheIterator">Looking more closely at the Iterator</a></h2>
<p>Let&#8217;s look at what is happening in more detail by examining what is happening behind the scenes during the iteration process. In order to illustrate what is happening in the for loop I will demonstrate the order in which things are being called behind the scenes.  </p>
<p>The first step in the iteration process is to call to the <code>__iter__</code> function in order to get the iterator object that will perform the iteration. Notice that this works on iterator and iterable objects, since iterators returns themselves and iterables return an iterator.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">iterator</span><span class="hl-default"> = </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">__iter__</span><span class="hl-brackets">()</span></pre></div></div>
<p>Now that we have the iterator object, we start iterating by calling the <code>next</code> function in order to get the next value:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()</span></pre></div></div>
<p>This executes the <code>next</code> function which will return the byte value of character in the string with which we are currently working. Since this is the first call to the <code>next</code> function <code>current_item</code> will be zero and we will calculate the byte value of the first character in our string (&#8217;a') resulting in:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-number">97</span></pre></div></div>
<p>If we continue the iteration process by calling the <code>next</code> function six more times we would get the results shown in Listing 3. Notice that we have now made a total of seven calls to the <code>next</code> function, one more then the number of characters in our string. I&#8217;m running the python code from a file (iter.py found in Listing 4). Depending on how you are running it, you might get slightly different results. However, the most important thing to observe in this example is the exception that is raised.</p>
<p><strong>Listing 3</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-number">97
98
99
100
101
102
</span><span class="hl-identifier">Traceback </span><span class="hl-brackets">(</span><span class="hl-identifier">most recent call last</span><span class="hl-brackets">)</span><span class="hl-default">:
  </span><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">Listing4.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">34</span><span class="hl-default">, </span><span class="hl-reserved">in</span><span class="hl-default"> ?
    </span><span class="hl-identifier">main</span><span class="hl-brackets">()
  </span><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">Listing4.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">30</span><span class="hl-default">, </span><span class="hl-reserved">in </span><span class="hl-identifier">main
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
  </span><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">Listing4.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">13</span><span class="hl-default">, </span><span class="hl-reserved">in </span><span class="hl-identifier">next
    </span><span class="hl-reserved">raise StopIteration
StopIteration</span></pre></div></div>
<p><strong>Listing 4</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</span><span class="hl-reserved">class </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">data</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default"> = </span><span class="hl-identifier">data
		self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-number">0
	</span><span class="hl-reserved">def </span><span class="hl-identifier">__iter__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self

	</span><span class="hl-reserved">def </span><span class="hl-identifier">next</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-code"> == </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-reserved">raise StopIteration
		else</span><span class="hl-default">:
			</span><span class="hl-identifier">byte_value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> += </span><span class="hl-number">1
			</span><span class="hl-reserved">return </span><span class="hl-identifier">byte_value
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-reserved">for </span><span class="hl-identifier">v </span><span class="hl-reserved">in </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abc</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">if </span><span class="hl-identifier">v </span><span class="hl-reserved">in </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abc</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">We have a %d</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">v

    bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">iterator</span><span class="hl-default"> = </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">__iter__</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
	</span><span class="hl-comment"># Someone is launching this directly
	</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>For the most part you won&#8217;t be calling an iterator object&#8217;s <code>__iter__</code> or <code>next</code> functions manually, instead you&#8217;ll probably just let the for loop do it all for you.</p>
<h2><a name="TheUpsideAndDownsideOfIterators">The upside and downside of Iterators</a></h2>
<p>Now that our class is an iterator object we can use any of the built-in functions and methods that work on iterators and iterables, such as: the <code>sum</code>, <code>tuple</code>, <code>sorted</code>, and <code>list</code> functions, to name a few.</p>
<p>In the first example the <code>bytes</code> function returned a list object that we could work with. If we want a list instead of an iterator for any reason, it will be as simple as using the <code>list</code> function, which takes an iterator as a parameter and returns a list:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-builtin">list</span><span class="hl-brackets">(</span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">))</span></pre></div></div>
<p>If we want a sorted list:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">sorted</span><span class="hl-brackets">(</span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">))</span></pre></div></div>
<p>If we want the sum of all of the bytes:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-builtin">sum</span><span class="hl-brackets">(</span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">))</span></pre></div></div>
<p>While very useful, iterators do have some downsides to them. The most obvious is that they are only good for one pass over the data. They also generally require you to add extra data members to your class in order to keep track of your current iterator position. Depending on what you are iterating over, this process can become quite complex.  Iterators also only allow you to perform one &#8220;type&#8221; of iteration, i.e., in one direction or over one piece of internal data.  You might address this by adding flags to your class but this will further clutter the class and decrease readability. So how can you simply add multiple types of iteration to a class? Enter the generator! </p>
<h2><a name="Generators">Generators</a></h2>
<p>A generator is a function that creates, or generates, an iterator. In order for a function to become a generator it must return a value using the <code>yield</code> keyword.</p>
<p>Generators are interesting because they are functions, yet execution does not run through them as it does in a normal function. The first time execution enters a generator function it will start at the beginning of the function and continue until the <code>yield</code> keyword is encountered. When the iteration continues, execution will continue in the generator function on the statement immediately following the <code>yield</code> keyword. All local variables in the function will remain intact. If the yield statement occurs within a loop, execution will continue within the loop as though execution had not been interrupted.</p>
<p>Continuing with the ByteValue example, let&#8217;s add a generator function named <code>reverse</code> that can be used to iterate through the byte vales of the string in reverse order:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">reverse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">)
	</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> -= </span><span class="hl-number">1
		</span><span class="hl-reserved">yield </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])</span></pre></div></div>
<p>So what&#8217;s going on here?  The first thing to notice is that we did not add anymore data members to our class, this generator is a self-contained unit. Secondly, since this is a generator, our counter <code>current_item</code> can be a local variable.</p>
<p>In the <code>reverse</code> function the first step is to initialize <code>current_item</code>, which represents the current character in the string, to be equal to the length our string. We initialize it to the length of the string instead of zero since we are iterating through the string in reverse.  Next we have a while loop that loops while <code>current_item</code> is greater than zero. We then subtract one from our counter, to give us the current character to process. Finally, we yield the byte value of the current character.</p>
<p><strong>Note:</strong> We subtract one from our counter the first time through the loop because Python is zero-based and the length of a list minus one gives us the position of the last item in the list. In our examples we have used the following string:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">abcdef
</span><span class="hl-number">012345</span></pre></div></div>
<p>When we calculate the length of the string we get 6. We then subtract 1 from that number, leaving 5, which is the index of the last number in the string.  </p>
<p>Making use of our new generator function, we run the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">for </span><span class="hl-identifier">byte </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">reverse</span><span class="hl-brackets">()</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-identifier">byte</span></pre></div></div>
<p>We get our favourite byte values in reverse:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-number">102
101
100
99
98
97</span></pre></div></div>
<h2><a name="LookingCloselyAtTheGenerator">Looking closely at the Generator</a></h2>
<p>Let&#8217;s take a detailed look at what is happening in the generator in the same way that we did earlier with the iterator object. The first thing that happens when you call a generator function is NOT the execution of the actual function, rather, it is the creation of a generator object. Running the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">gen</span><span class="hl-default"> = </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">reverse</span><span class="hl-brackets">()
</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span></pre></div></div>
<p>will result in:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-default">&lt;</span><span class="hl-identifier">generator object at </span><span class="hl-number">0</span><span class="hl-identifier">xb7d8e04c</span><span class="hl-default">&gt;</span></pre></div></div>
<p>This demonstrates that, as stated above, the first call to our generator function does not return the byte value of that last character in the string, instead it creates a generator object. In fact the first time a generator function is called, the actual function is not executed at all. A generator object is &#8220;what Python uses to implement generator iterators. They are normally created by iterating over a function that yields values&#8221;.<a href="#3">[3]</a></p>
<p>Once we have a generator object we can start calling its <code>next</code> function (sound familiar?) to perform the action iteration. An example of this can be found in Listing 5. The results of this execution can be found in Listing 6. The results will seem very familiar to you, especially the <code>StopIteration</code> exception.</p>
<p><strong>Listing 5</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</span><span class="hl-reserved">class </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">data</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default"> = </span><span class="hl-identifier">data
		self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-number">0
	</span><span class="hl-reserved">def </span><span class="hl-identifier">__iter__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self

	</span><span class="hl-reserved">def </span><span class="hl-identifier">next</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-code"> == </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-reserved">raise StopIteration
		else</span><span class="hl-default">:
			</span><span class="hl-identifier">byte_value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> += </span><span class="hl-number">1
			</span><span class="hl-reserved">return </span><span class="hl-identifier">byte_value
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data

	</span><span class="hl-reserved">def </span><span class="hl-identifier">reverse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">)
		</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-identifier">current_item</span><span class="hl-default"> -= </span><span class="hl-number">1
			</span><span class="hl-reserved">yield </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:

	</span><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">gen</span><span class="hl-default"> = </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">reverse</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
	</span><span class="hl-comment"># Someone is launching this directly
	</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p><strong>Listing 6</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-number">102
101
100
99
98
97
</span><span class="hl-identifier">Traceback </span><span class="hl-brackets">(</span><span class="hl-identifier">most recent call last</span><span class="hl-brackets">)</span><span class="hl-default">:
  </span><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">Listing5.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">40</span><span class="hl-default">, </span><span class="hl-reserved">in</span><span class="hl-default"> ?
    </span><span class="hl-identifier">main</span><span class="hl-brackets">()
  </span><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">Listing5.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">36</span><span class="hl-default">, </span><span class="hl-reserved">in </span><span class="hl-identifier">main
    </span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
</span><span class="hl-reserved">StopIteration</span></pre></div></div>
<p>If we want to look at the contents of the generator object we could use the following code:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">print </span><span class="hl-builtin">dir</span><span class="hl-brackets">(</span><span class="hl-identifier">gen</span><span class="hl-brackets">)</span></pre></div></div>
<p>And getting the following results:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">__class__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__delattr__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__doc__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__getattribute__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__hash__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__init__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__iter__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__new__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__reduce__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__reduce_ex__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__repr__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__setattr__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__str__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">gi_frame</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">gi_running</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">next</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span></pre></div></div>
<p>Notice that the generator object contains the <code>__iter__</code> and <code>next</code> functions making the generator object itself an iterator. Because the generator itself is an iterator object, the same built-in iterator functions I mentioned earlier can also be used on our generators:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">print </span><span class="hl-builtin">sum</span><span class="hl-brackets">(</span><span class="hl-identifier">bv</span><span class="hl-code">.</span><span class="hl-identifier">reverse</span><span class="hl-brackets">())</span></pre></div></div>
<p>It is also important to remember that your generator or iterator does not have to perform only &#8220;dumb&#8221; iteratation, simply moving through some sort of an internal list. Rather, it can make decisions just like any other block of code.</p>
<p>For example, let’s say that in our <code>reverse</code> generator we want to use the byte value 99 as an end condition. We can do something similar to the example found in Listing 7.</p>
<p><strong>Listing 7</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">reverse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">)
	</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> -= </span><span class="hl-number">1
		</span><span class="hl-identifier">value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">value</span><span class="hl-code"> == </span><span class="hl-number">99</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-reserved">return
		yield </span><span class="hl-identifier">value</span></pre></div></div>
<p>In Listing 7 if the byte value equals 99 we return from our generator function using the <code>return</code> keyword. Since we didn&#8217;t yield anything this will cause the <code>StopIteration</code> exception to be fired halting the iteration.</p>
<p>Be careful about getting too smart with your iteration because you cannot return any information from a generator you can only yield it. So if you tried to execute the code in Listing 8, in an attempt to return one last value before quitting (or if you wanted to return a success or failure code) you will get the following error when the <code>return value</code> line of code is executed:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">SyntaxError</span><span class="hl-default">: </span><span class="hl-quotes">'</span><span class="hl-string">return</span><span class="hl-quotes">' </span><span class="hl-identifier">with argument inside generator</span></pre></div></div>
<p><strong>Listing 8</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">reverse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">)
	</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> -= </span><span class="hl-number">1
		</span><span class="hl-identifier">value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">value</span><span class="hl-code"> == </span><span class="hl-number">99</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-reserved">return </span><span class="hl-identifier">value
		</span><span class="hl-reserved">yield </span><span class="hl-identifier">value</span></pre></div></div>
<h2><a name="ButWhatAboutIterables">But what about iterables?</a></h2>
<p>I&#8217;m sure that by now you are wondering about the iterable objects that I mentioned at the start of this tutorial. As you have probably guessed, simply making your class an iterator isn&#8217;t that useful unless it is only performing one task like our ByteValue example. Since your classes will generally be performing more than one task, you will likely want to make your class an iterable object rather than an iterator object. To recap, iterable objects return an iterator object when their <code>__iter__</code> function is called, which allows for multiple passes over their data.</p>
<h2><a name="CreatingAnIterableObject">Creating an Iterable object</a></h2>
<p>Since the definition of an iterable object is an object that returns an iterator object when its <code>__iter__</code> function is called, creating an iterable object can be done in a variety of ways. Two options that come to mind are: 1)creating an iterator helper class to perform the iteration and, 2) using a generator function. I prefer using a generator function since it keeps the functionality within the main class.</p>
<p>See Listing 9 for an example of creating an iterarable object using a generator. You will see that we have replaced the <code>next</code> function with the <code>forward</code> function. The <code>forward</code> function is a generator that iterates through the data in the &#8220;forward&#8221; direction. In the <code>__iter__</code> function we return the <strong>results</strong> of a call to the <code>forward</code> function, a generator object. Since generator objects contain the iterator protocol and are, in fact iterators, by returning one from our <code>__init__</code> function we have successfully created an iterable.</p>
<p><strong>Listing 9</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">data</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default"> = </span><span class="hl-identifier">data

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__iter__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#We are an iterable, so return our iterator
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">forward</span><span class="hl-brackets">()

	</span><span class="hl-reserved">def </span><span class="hl-identifier">forward</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#The forward generator
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-number">0
		</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &lt; </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-identifier">byte_value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
			</span><span class="hl-identifier">current_item</span><span class="hl-default"> += </span><span class="hl-number">1
			</span><span class="hl-reserved">yield </span><span class="hl-identifier">byte_value

	</span><span class="hl-reserved">def </span><span class="hl-identifier">reverse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#The reverse generator
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">)
		</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-identifier">current_item</span><span class="hl-default"> -= </span><span class="hl-number">1
			</span><span class="hl-reserved">yield </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abc</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-reserved">for </span><span class="hl-identifier">v </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">:
        </span><span class="hl-reserved">if </span><span class="hl-identifier">v </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">We have a %d</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">v

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>Now that we have an iterable object, we can iterate over it as many times as we want. We can even have fun with nested iteration:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">for </span><span class="hl-identifier">value </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-identifier">value
	</span><span class="hl-reserved">for </span><span class="hl-identifier">second_value </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">:
		</span><span class="hl-reserved">print </span><span class="hl-identifier">second_value</span></pre></div></div>
<h2><a name="Conclusion">Conclusion</a></h2>
<p>This concludes our introduction to iterators, iterables, and generators. I hope I have demonstrated the immense power and flexibility that they provide. In general, making your object an iterable object and/or using generators allows for more flexibility than simple iterator objects provide. For most complex classes or complex sets of data, multiple iterations are a given.</p>
<p>With all of the praise that I have heaped upon iterators, iterables, and generators, it&#8217;s important to remember that they are not a panacea and should not be used in every case where a sequence of items is needed. There are many instances where a returning a list is the desired result. This being said, iterators, iterables, and generators are extremely useful and provide a great way to loop through data.</p>
<p><a name="1">[1]</a> <a href="http://docs.python.org/tut/node18.html">http://docs.python.org/tut/node18.html</a><br />
<a name="2">[2]</a> <a href="http://docs.python.org/lib/typeiter.html">http://docs.python.org/lib/typeiter.html</a><br />
<a name="3">[3]</a> <a href="http://docs.python.org/api/gen-objects.html">http://docs.python.org/api/gen-objects.html</a></generator></p>
<div style="float:right;margin:0px 0px 0px 0px;"><a href="http://www.google.com/reader/link?url=http://www.learningpython.com/2009/02/23/iterators-iterables-and-generators-oh-my/&title=Iterators, Iterables, and Generators! Oh, my!&srcTitle=learning python&srcURL=http://www.learningpython.com"target="_blank" rel=""><img border="0" src="http://www.learningpython.com/wp-content/plugins/wp-google-buzz/icon/12.png" style="opacity:1;filter:alpha(opacity=100)" onmouseover="this.style.opacity=0.8;this.filters.alpha.opacity=70" onmouseout="this.style.opacity=1;this.filters.alpha.opacity=100"/> </a></div>]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2009/02/23/iterators-iterables-and-generators-oh-my/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
	</channel>
</rss>
