py - understanding zip function

understanding zip function

from: http://stackoverflow.com/questions/3865640/understanding-zip-function

All discussion is about python 3.1.2; see Python docs for the source of my question.

I know what zip does; I just don't understand why it can be implemented like this:

def zip(*iterables):
    # zip('ABCD', 'xy') --> Ax By
    iterables = map(iter, iterables)
    while iterables:
        yield tuple(map(next, iterables))

Let's say I call zip(c1, c2, c3). If I understand correctly, iterables is initially the tuple (c1, c2, c3).

The line iterables = map(iter, iterables) converts it to an iterator that would return iter(c1), iter(c2), iter(c3) if iterated through.

Inside the loop, map(next, iterables) is an iterator that would return next(iter(c1))next(iter(c2)), and next(iter(c3)) if iterated through. The tuple call converts it to (next(iter(c1)), next(iter(c2)), next(iter(c3)), exhausting its argument (iterables) on the very first call as far as I can tell. I don't understand how the while loop manages to continue given that it checks iterables; and if it does continue why the tuple call doesn't return empty tuple (the iterator being exhausted).

I'm sure I'm missing something very simple..

share improve this question
 
 
Weird, it loops endlessly for me even though it looks perfectly fine... and my own attempt doesn't work either o.O I am shocked. –  delnan  Oct 5 '10 at 17:14 
 
I think this is just pseudocode and shouldn't be taken literally. –  Radomir Dopieralski  Oct 5 '10 at 17:16
1 
@Radomir Dopieralski It's Python code, not pseudocode, copied directly from the documentation. I would be quite sad if I couldn't rely on it, and instead had to make my best guess about what the function really does. I refer to the code like this whenever I am not 100% sure about the function's semantics. –  max  Oct 5 '10 at 17:19 
 
I guess you can learn from this that no-one is perfect. –  Douglas Leeder  Oct 5 '10 at 18:21

2 Answers

up vote 8 down vote accepted

It looks like it's a bug in the documentation. The 'equivalent' code works in python2 but not in python3, where it goes into an infinite loop.

And the latest version of the documentation has the same problem:http://docs.python.org/release/3.1.2/library/functions.html

Looks like change 61361 was the problem, as it merged changes from python 2.6 without verifying that they were correct for python3.

It looks like the issue doesn't exist on the trunk documentation set, but you probably should report a bug about it at http://bugs.python.org/.

share improve this answer
 
 
Ok, reported. To clarify: the while will evaluate to true because iterables is an iterator; and iterator always evaluates to true regardless of its contents. Furthermore, the iterables will exhausted on the first run through the loop, so it would keep yielding empty tuple thereafter. Correct? –  max  Oct 5 '10 at 18:37
 
@max: it will evaluate to True because iterables is a non-empty list. Did you even read what I've posted? –  SilentGhost  Oct 5 '10 at 18:42 
 
Sorry missed your answer :( So if run in Python 2, it would be true because iterables list isn't empty; but if run in Python 3 (which I assumed in my comment), it would be true because iterables is an iterator, and iterator always evaluates to true, correct? –  max  Oct 5 '10 at 18:49
 
@max: that's right. –  SilentGhost  Oct 5 '10 at 18:59
 
@max: Thanks for raising that bug. –  Douglas Leeder  Oct 6 '10 at 9:02

It seems like this code is supposed to be read as python-2.x code. It doesn't even run properly in py3k.

What happens in python-2.x is that map return a list of iterators, when next is called it returns an element of iterator, those elements combined into tuple. So, given

>>> zip('ABCD', 'xy')

iterables is a list of 2 iterators, on each iteration within the while loop, next (first remaining) element of iterator is consumed (''A' and 'x', etc), and yielded as an element of a tuple, then after last elements are yielded, (on 3rd iteration) raised StopIteration stops the generator. while iterablesalways remains True.

share improve this answer
 
 
+1 for python-2.x explanation.. –  max  Oct 5 '10 at 18:52
 
@max it's tagged python-3. First sentence says it's just about python 3. Why upvote on the basis that the answer is for python-2? Ditto Ruby, or anything else that isn't python-3? –  Robert Grant  Apr 16 '15 at 13:55
 
@RobertGrant because referring to python 2 was the only way to explain how the the official python documentation was apparently completely wrong. –  max  Apr 16 '15 at 19:37



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值