can list comprehensions replace map?
Andrew Dalke
dalke at dalkescientific.com
Thu Jul 28 03:05:58 EDT 2005
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
for x in zipfill("This", "is", "only", "a", "test."):
print x
This generates
['T', 'i', 'o', 'a', 't']
['h', 's', 'n', None, 'e']
['i', None, 'l', None, 's']
['s', None, 'y', None, 't']
[None, None, None, None, '.']
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]
(I originally had a "element == tuple([sentinel]*len(seqs))" check
but didn't like all the == tests incurred.)
Andrew
dalke at dalkescientific.com
More information about the Python-list
mailing list