py - understanding zip function
来源:互联网 发布:tuxera ntfs for mac 编辑:程序博客网 时间:2024/06/14 09:45
understanding zip function
from: http://stackoverflow.com/questions/3865640/understanding-zip-functionup vote12down votefavorite6All 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..
python iterator zip python-3.x 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:161 @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:21add a comment2 Answers
activeoldestvotesup vote8down voteIt 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/.
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:02add a commentup vote7down voteIt 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 iterables
always remains True
.
+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
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..
2 Answers
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/.
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:37True
because iterables
is a non-empty list. Did you even read what I've posted? – SilentGhost Oct 5 '10 at 18:42 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 iterables
always remains True
.
- py - understanding zip function
- zip function
- Understanding the JavaScript __doPostBack Function
- python-function-zip
- python study ------- zip function
- Understanding this, $(this), and event in a JQuery callback function
- Understanding
- py
- py
- py
- py
- py
- py
- py
- Py
- zip
- zip
- zip
- POJ 1113 Wall(求凸包周长)
- leetcode笔记:Remove Linked List Elements
- 1012 of search
- HTTP 请求方式: GET和POST的比较 3
- git历史版本修改合并到主分支
- py - understanding zip function
- POJ 2007 Scrambled Polygon(极角排序)
- Navicat for MySql 如何插入新记录
- linux开机启动流程
- POJ 1873 The Fortified Forest(凸包+DFS枚举)
- and5.1PowerManagerService深入分析(四)PMS与Display模块
- URI和URL的区别
- Codewars-Javascript训练手册:字符串(上)
- java的访问权限