Simple exercise

Steven D'Aprano steve at pearwood.info
Mon Mar 14 19:59:48 EDT 2016


On Tue, 15 Mar 2016 02:06 am, Oscar Benjamin wrote:

> On 14 March 2016 at 14:35, Rick Johnson <rantingrickjohnson at gmail.com>
> wrote:
>>
>> I would strongly warn anyone against using the zip function
>> unless
> ...
>> I meant to say: absolutely, one hundred percent *SURE*, that
>> both sequences are of the same length, or, absolutely one
>> hundred percent *SURE*, that dropping values is not going to
>> matter. For that reason, i avoid the zip function like the
>> plague. I would much rather get an index error, than let an
>> error pass silently.
> 
> I also think it's unfortunate that zip silently discards items. 

Are you aware of itertools.zip_longest?

That makes it easy to build a zip_strict:

def zip_strict(*iterables):
    pad = object()
    for t in itertools.zip_longest(*iterables, fillvalue=pad):
        if pad in t:
            raise ValueError("iterables of different length")
        yield t


Unfortunate or not, it seems to be quite common that "zip" (convolution)
discards items when sequences are of different lengths. I think the usual
intent is so that you can zip an infinite (or near infinite) sequence of
counters 1, 2, 3, 4, ... with the sequence you actually want, to get the
equivalent of Python's enumerate().

Clojure, Common Lisp, Haskell all halt on the shortest sequence, like
Python; D is configurable with a stopping policy:

(shortest, longest, requiresSameLength)

but the effect of these are not documented well.

http://dlang.org/phobos/std_range.html#zip

Ruby's zip pads missing values with nil, but only relative to the *first*
argument:

irb(main):001:0> a = [1, 2, 3]
=> [1, 2, 3]
irb(main):002:0> b = [10, 20]
=> [10, 20]
irb(main):003:0> a.zip(b)
=> [[1, 10], [2, 20], [3, nil]]
irb(main):004:0> b.zip(a)
=> [[10, 1], [20, 2]]


F# also has a zip function, but I don't know what it does.

Scheme doesn't appear to have a built-in zip function, but it is easily
written using map, giving the halt-on-shortest behaviour:

(define (zip l1 l2)(map list l1 l2))


See https://en.wikipedia.org/wiki/Convolution_%28computer_science%29



-- 
Steven




More information about the Python-list mailing list