[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