can list comprehensions replace map?

Peter Otten __peter__ at web.de
Fri Jul 29 03:59:22 EDT 2005


Andrew Dalke wrote:

> Steven Bethard wrote:
>> Here's one possible solution:
>> 
>> py> import itertools as it
>> py> def zipfill(*lists):
>> ...  max_len = max(len(lst) for lst in lists)
> 
> A limitation to this is the need to iterate over the
> lists twice, which might not be possible if one of them
> is a file iterator.
> 
> Here's a clever, though not (in my opinion) elegant solution
> 
> import itertools
> 
> def zipfill(*seqs):
>     count = [len(seqs)]
>     def _forever(seq):
>         for item in seq: yield item
>         count[0] -= 1
>         while 1: yield None
>     seqs = [_forever(seq) for seq in seqs]
>     while 1:
>         x = [seq.next() for seq in seqs]
>         if count == [0]:
>             break
>         yield x
 

> This seems a bit more elegant, though the "replace" dictionary is
> still a bit of a hack
> 
> from itertools import repeat, chain, izip
> 
> sentinel = object()
> end_of_stream = repeat(sentinel)
> 
> def zipfill(*seqs):
>     replace = {sentinel: None}.get
>     seqs = [chain(seq, end_of_stream) for seq in seqs]
>     for term in izip(*seqs):
>         for element in term:
>             if element is not sentinel:
>                 break
>         else:
>             # All sentinels
>             break
>             
>         yield [replace(element, element) for element in term]

Combining your "clever" and your "elegant" approach to something fast
(though I'm not entirely confident it's correct):

def fillzip(*seqs):
    def done_iter(done=[len(seqs)]):
        done[0] -= 1
        if not done[0]:
            return
        while 1:
            yield None
    seqs = [chain(seq, done_iter()) for seq in seqs]
    return izip(*seqs)

Whether we ran out of active sequences is only tested once per sequence.

Fiddling with itertools is always fun, but feels a bit like reinventing the
wheel in this case. The only excuse being that you might need a lazy
map(None, ...) someday...

Peter




More information about the Python-list mailing list