defining the behavior of zip(it, it) (WAS: Converting a flat list...)

Steven Bethard steven.bethard at gmail.com
Wed Nov 23 12:18:16 EST 2005


bonono at gmail.com wrote:
> Steven Bethard wrote:
> 
>>rhettinger at gmail.com wrote:
>>
>>>>>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).
>>>>>"""
>>>>>IMO left->right is useful enough to warrant making it defined
>>>>>behaviour
>>>>
>>>>And in fact, it is defined behavior for itertools.izip() [1].
>>>>
>>>>I don't see why it's such a big deal to make it defined behavior for
>>>>zip() too.
>>>
>>>
>>>IIRC, this was discussednd rejected in an SF bug report.  It should not
>>>be a defined behavior for severals reasons:
>>
>>[snip arguments about how confusing zip(it, it) is]
>>
>>>Overall, I think anyone using zip(it,it) is living in a state of sin,
>>>drawn to the tempations of one-liners and premature optimization.  They
>>>are forsaking obvious code in favor of screwy special cases.  The
>>>behavior has been left undefined for a reason.
>>
>>Then why document itertools.izip() as it is?  The documentation there is
>>explicit enough to know that izip(it, it) will work as intended.  Should
>>we make the documentation there less explicit to discourage people from
>>using the izip(it, it) idiom?
> 
[snip]
> 
> But technically speaking, you are still referring to the implementation
> detail of izip(), not the functionality of izip().
> 
> I do now agree with another poster that the documentation of both zip
> and izip should state clear that the order of picking from which
> iterable is undefined or can be changed from implementation to
> implementation, to avoid this kind of temptation.
> 

Actually, it's part of the specificiation.  Read the itertools 
documentation[1]:

"""
izip(*iterables)
     Make an iterator that aggregates elements from each of the 
iterables. Like zip() except that it returns an iterator instead of a 
list. Used for lock-step iteration over several iterables at a time. 
Equivalent to:

      def izip(*iterables):
          iterables = map(iter, iterables)
          while iterables:
              result = [i.next() for i in iterables]
              yield tuple(result)
"""

So technically, since itertools.izip() is "equivalent to" the Python 
code above, it is part of the specification, not the implementation.

But I certainly understand Raymond's point -- the code in the itertools 
documentation there serves a number of purposes other than just 
documenting the behavior.

[1]http://docs.python.org/lib/itertools-functions.html#l2h-1392

STeVe



More information about the Python-list mailing list