[ python-Bugs-1121416 ] zip incorrectly and incompletely documented

SourceForge.net noreply at sourceforge.net
Sun Feb 13 03:25:32 CET 2005


Bugs item #1121416, was opened at 2005-02-13 03:18
Message generated for change (Comment added) made by ncoghlan
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1121416&group_id=5470

Category: Documentation
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Alan (aisaac0)
Assigned to: Raymond Hettinger (rhettinger)
Summary: zip incorrectly and incompletely documented

Initial Comment:
See the zip documentation:
http://www.python.org/dev/doc/devel/lib/built-in-funcs.html

i. documentation refers to sequences not to iterables

ii. The other problem is easier to explain by example.
Let it=iter([1,2,3,4]).
What is the result of zip(*[it]*2)?
The current answer is: [(1,2),(3,4)],
but it is impossible to determine this from the docs,
which would allow [(1,3),(2,4)] instead (or indeed
other possibilities).

The example expresses the solution to an actual need,
so the behavior should be documented or warned against,
I believe.

----------------------------------------------------------------------

Comment By: Nick Coghlan (ncoghlan)
Date: 2005-02-13 12:25

Message:
Logged In: YES 
user_id=1038590

The generator in the previous comment was incorrect (tuple
swallows the StopIteration, so it never terminates). Try
this instead:

def partition(iterable, part_len):
    itr = iter(iterable)
    while 1:
        item = tuple(islice(itr, part_len))
        if len(item) < part_len:
            raise StopIteration
        yield item 


----------------------------------------------------------------------

Comment By: Nick Coghlan (ncoghlan)
Date: 2005-02-13 11:30

Message:
Logged In: YES 
user_id=1038590

Raymond's point about opaqueness is well-taken, since the
given partitioning behaviour in the example was actually
what was intended (I was part of the relevant c.l.p discussion).

For future reference, the reliable approach is to use a
generator function instead:

from itertools import islice
def partition(iterable, part_len):
    itr = iter(iterable)
    while 1:
        yield tuple(islice(itr, part_len))


----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2005-02-13 05:50

Message:
Logged In: YES 
user_id=80475

The problem with your example does not lie with zip(). 
Instead, there is a misunderstanding of iter() and how
iterators are consumed.  Instead of iter(), the correct
function is itertools.tee():
>>> zip(*tee([1,2,3,4]))
[(1, 1), (2, 2), (3, 3), (4, 4)]

Also, stylistically, the zip(*func) approach is too opaque.
 It is almost always better (at least for other readers and
possibly for yourself) to write something more obvious in
its intent and operation.  List comprehensions and generator
expressions are often more clear and easier to write correctly:
>>> [(x,x) for x in [1,2,3,4]]
[(1, 1), (2, 2), (3, 3), (4, 4)]

I do agree that the word sequence should be dropped because
it implies that non-sequence iterables are not acceptable as
arguments.  That's too bad because the word "sequence" seems
to help people understand what zip is doing.

You're correct that the zip docs do not describe its
implementation in such detail as to be able to predict the
[(1,2),(3,4)] result.  However, that would be an
over-specification.  That particular result is an
implementation specific detail that is subject to change. 
It probably won't change, but we don't want to encourage
people to write code that relies on the specific order of
operations within zip().  If someone wants to do something
tricky, such as [(1,2),(3,4)], then they are better off
writing an explicit loop so that the order of operation is
clear both to themselves and to code reviewers.


----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1121416&group_id=5470


More information about the Python-bugs-list mailing list