[Tutor] Strange zip syntax

Albert-Jan Roskam fomcl at yahoo.com
Fri Sep 16 15:16:17 CEST 2011


Hi,
 
I would write the slightly longer, but more readable (for me at least) code:
>>> a = ['a','1','b','2','c','3']
>>> [(a[i], a[i+1]) for i in range(0, len(a), 2)]
[('a', '1'), ('b', '2'), ('c', '3')]
>>> zip(*[iter(a)]*2)
[('a', '1'), ('b', '2'), ('c', '3')]
 
And it's also faster:
 
>>> import timeit
>>> t = timeit.Timer("zip(*[iter(['a', '1', 'b', '2', 'c', '3'])]*2)")
>>> t.timeit()
5.1758860413823555
>>> t = timeit.Timer("a=['a', '1', 'b', '2', 'c', '3']; [(a[i], a[i+1]) for i in range(0, len(a), 2)]")
>>> t.timeit()
2.5330216549868823
>>> 

Cheers!!
Albert-Jan


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a fresh water system, and public health, what have the Romans ever done for us?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

From: Brett Ritter <swiftone at swiftone.org>
>To: *tutor python <tutor at python.org>
>Sent: Friday, September 16, 2011 4:35 AM
>Subject: [Tutor] Strange zip syntax
>
>I ran into this article (
>http://blog.adku.com/2011/09/hodgepodge-of-python.html ) and found
>myself temporarily stymied by one line it in:
>
>zip(*[iter(a)]*2)
>
>Used like this:
>
>>>> a = ['a','1','b','2','c','3']
>>>> zip(*[iter(a)]*2)
>[('a', '1'), ('b', '2'), ('c', '3')]
>
>While I'm unlikely to use such a construct (if I can't easily follow
>it now, I or my successor likely won't follow it should it need to be
>debugged sometime in the future), I found the education I got in
>deciphering it was worth the effort.  I'm sharing it here so others
>can benefit from my puzzlement.
>
>iter(a) returns a list iterator for a.  See help(iter) for more.
>[iter(a)] is a list containing one element, an iterator.  This is
>created only so we can do the below:
>[iter(a)]*2 is a list containing two elements, each the SAME list iterator.
>For simplicity, let's break this out for further analysis:
>
>>>> b = iter(a)
>>>> c = [b,b]
>
>*[iter(a)]*2 flattens the list when passed into a function call.
>Using our more verbose but simple syntax: *c.  This only works when
>passed to a function.
>zip() creates tuples each holding the Nth elements from a number of
>sequences.  See help(zip) for more.
>Thus, zip(a) or zip(a,a) would return:
>>>> zip(a)
>[('a',), ('1',), ('b',), ('2',), ('c',), ('3',)]
>>>> zip(a,a)
>[('a', 'a'), ('1', '1'), ('b', 'b'), ('2', '2'), ('c', 'c'), ('3', '3')]
>
>What happens when we pass an iterator to zip?  That's not mentioned in
>the docstring blurb.
>>>> zip(iter(a))
>[('a',), ('1',), ('b',), ('2',), ('c',), ('3',)]
>Answer: It works as intended.
>
>Now we come to the magic of this little snippet.
>zip(iter(a),iter(a)) wouldn't work, because each call to iter(a)
>returns a DIFFERENT iterator.
>>>> zip(iter(a), iter(a))
>[('a', 'a'), ('1', '1'), ('b', 'b'), ('2', '2'), ('c', 'c'), ('3', '3')]
>
>But by creating the list of two elements each of which is the SAME
>iterator, as each is asked to iterate it advances the common element
>indicator:
>>>> zip(*c)
>[('a', '1'), ('b', '2'), ('c', '3')]
>Notice that the flattening is required, because zip needs to get
>multiple arguments:
>>>> b = iter(a)  #our original iterator is spent, so we're assigning a new one
>>>> c = [b,b]
>>>> zip(c)  #Not flattened, is just a single list, like a.
>[(<listiterator object at 0x024E32D0>,), (<listiterator object at 0x024E32D0>,)]
>>>> zip(b,b)  # here it is two iterators sent to zip() (though they happen to be the SAME iterator)
>[('a', '1'), ('b', '2'), ('c', '3')]
>
>I hope some of you enjoy playing with this, and hopefully someone
>learned something useful!  While I'm not likely to use the listed
>form, I can very well see myself saying:
>
>>>> a = ['a','1','b','2','c','3']  #well, I can see myself using this with meaningful variable names
>>>> b = iter(a)
>>>> zip(b,b)  # Group in sets of 2 elements
>
>-- 
>Brett Ritter / SwiftOne
>swiftone at swiftone.org
>_______________________________________________
>Tutor maillist  -  Tutor at python.org
>To unsubscribe or change subscription options:
>http://mail.python.org/mailman/listinfo/tutor
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20110916/9acc3e1b/attachment-0001.html>


More information about the Tutor mailing list