<div>iBrett,</div>
<div> </div>
<div>iter<br><br></div>
<div class="gmail_quote">On Fri, Sep 16, 2011 at 3:35 AM, Brett Ritter <span dir="ltr">&lt;<a href="mailto:swiftone@swiftone.org">swiftone@swiftone.org</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">I ran into this article (<br><a href="http://blog.adku.com/2011/09/hodgepodge-of-python.html" target="_blank">http://blog.adku.com/2011/09/hodgepodge-of-python.html</a> ) and found<br>
myself temporarily stymied by one line it in:<br><br>zip(*[iter(a)]*2)<br><br>Used like this:<br><br>&gt;&gt;&gt; a = [&#39;a&#39;,&#39;1&#39;,&#39;b&#39;,&#39;2&#39;,&#39;c&#39;,&#39;3&#39;]<br>&gt;&gt;&gt; zip(*[iter(a)]*2)<br>
[(&#39;a&#39;, &#39;1&#39;), (&#39;b&#39;, &#39;2&#39;), (&#39;c&#39;, &#39;3&#39;)]<br><br>While I&#39;m unlikely to use such a construct (if I can&#39;t easily follow<br>it now, I or my successor likely won&#39;t follow it should it need to be<br>
debugged sometime in the future), I found the education I got in<br>deciphering it was worth the effort.  I&#39;m sharing it here so others<br>can benefit from my puzzlement.<br><br>iter(a) returns a list iterator for a.  See help(iter) for more.<br>
[iter(a)] is a list containing one element, an iterator.  This is<br>created only so we can do the below:<br>[iter(a)]*2 is a list containing two elements, each the SAME list iterator.<br>For simplicity, let&#39;s break this out for further analysis:<br>
<br>&gt;&gt;&gt; b = iter(a)<br>&gt;&gt;&gt; c = [b,b]<br></blockquote>
<div> </div>
<div>iter(c) returns listiterator </div>
<div> </div>
<div> </div>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid"><br>*[iter(a)]*2 flattens the list when passed into a function call.<br>Using our more verbose but simple syntax: *c.  This only works when<br>
passed to a function.<br>zip() creates tuples each holding the Nth elements from a number of<br>sequences.  See help(zip) for more.<br>Thus, zip(a) or zip(a,a) would return:<br>&gt;&gt;&gt; zip(a)<br>[(&#39;a&#39;,), (&#39;1&#39;,), (&#39;b&#39;,), (&#39;2&#39;,), (&#39;c&#39;,), (&#39;3&#39;,)]<br>
&gt;&gt;&gt; zip(a,a)<br>[(&#39;a&#39;, &#39;a&#39;), (&#39;1&#39;, &#39;1&#39;), (&#39;b&#39;, &#39;b&#39;), (&#39;2&#39;, &#39;2&#39;), (&#39;c&#39;, &#39;c&#39;), (&#39;3&#39;, &#39;3&#39;)]<br><br>What happens when we pass an iterator to zip?  That&#39;s not mentioned in<br>
the docstring blurb.<br>&gt;&gt;&gt; zip(iter(a))<br>[(&#39;a&#39;,), (&#39;1&#39;,), (&#39;b&#39;,), (&#39;2&#39;,), (&#39;c&#39;,), (&#39;3&#39;,)]<br>Answer: It works as intended.<br><br>Now we come to the magic of this little snippet.<br>
zip(iter(a),iter(a)) wouldn&#39;t work, because each call to iter(a)<br>returns a DIFFERENT iterator.<br>&gt;&gt;&gt; zip(iter(a), iter(a))<br>[(&#39;a&#39;, &#39;a&#39;), (&#39;1&#39;, &#39;1&#39;), (&#39;b&#39;, &#39;b&#39;), (&#39;2&#39;, &#39;2&#39;), (&#39;c&#39;, &#39;c&#39;), (&#39;3&#39;, &#39;3&#39;)]<br>
<br>But by creating the list of two elements each of which is the SAME<br>iterator, as each is asked to iterate it advances the common element<br>indicator:<br>&gt;&gt;&gt; zip(*c)<br>[(&#39;a&#39;, &#39;1&#39;), (&#39;b&#39;, &#39;2&#39;), (&#39;c&#39;, &#39;3&#39;)]<br>
Notice that the flattening is required, because zip needs to get<br>multiple arguments:<br>&gt;&gt;&gt; b = iter(a)  #our original iterator is spent, so we&#39;re assigning a new one<br>&gt;&gt;&gt; c = [b,b]<br>&gt;&gt;&gt; zip(c)   #Not flattened, is just a single list, like a.<br>
[(&lt;listiterator object at 0x024E32D0&gt;,), (&lt;listiterator object at 0x024E32D0&gt;,)]<br>&gt;&gt;&gt; zip(b,b)   # here it is two iterators sent to zip() (though they happen to be the SAME iterator)<br>[(&#39;a&#39;, &#39;1&#39;), (&#39;b&#39;, &#39;2&#39;), (&#39;c&#39;, &#39;3&#39;)]<br>
<br>I hope some of you enjoy playing with this, and hopefully someone<br>learned something useful!  While I&#39;m not likely to use the listed<br>form, I can very well see myself saying:<br><br>&gt;&gt;&gt; a = [&#39;a&#39;,&#39;1&#39;,&#39;b&#39;,&#39;2&#39;,&#39;c&#39;,&#39;3&#39;]   #well, I can see myself using this with meaningful variable names<br>
&gt;&gt;&gt; b = iter(a)<br>&gt;&gt;&gt; zip(b,b)  # Group in sets of 2 elements<br><font color="#888888"><br>--<br>Brett Ritter / SwiftOne<br><a href="mailto:swiftone@swiftone.org">swiftone@swiftone.org</a><br>_______________________________________________<br>
Tutor maillist  -  <a href="mailto:Tutor@python.org">Tutor@python.org</a><br>To unsubscribe or change subscription options:<br><a href="http://mail.python.org/mailman/listinfo/tutor" target="_blank">http://mail.python.org/mailman/listinfo/tutor</a><br>
</font></blockquote></div><br><br clear="all"><br>-- <br><i>Satajanus  Nig. Ltd<br><br><br></i><br>