Newbie: Struggling again 'map'
George Sakkis
george.sakkis at gmail.com
Sat May 26 13:10:11 EDT 2007
On May 26, 7:47 am, Roel Schroeven <rschroev_nospam... at fastmail.fm>
wrote:
> mosscliffe schreef:
>
> > for x,y in map("N/A", lista, listb): ########## Fails - Can not call a
> > 'str'
> > print "MAP:", x, "<<x y>>", y
>
> > def fillwith(fillchars):
> > return fillchars
>
> > for x,y in map(fillwith("N/A"), lista, listb): ########## Fails also -
> > Can not call a 'str'
> > print "MAP:", x, "<<x y>>", y
>
> The first argument to map is a function, which is called with the items
> of the argument sequences. If the first argument is None, a default
> function is used which returns a tuple of the items. In the case that
> two input sequences are provided:
>
> map(None, lista, listb)
>
> is equivalent to:
>
> def maketuple(a, b):
> return a, b
> map(maketuple, lista, listb)
>
> So what you want to do can be done with map like this:
>
> def make_fill_missing(fillchars):
> def fill_missing(a, b):
> if a is None:
> a = fillchars
> if b is None:
> b = fillchars
> return a, b
> return fill_missing
>
> map(make_fill_missing("N/A"), lista, listb))
And here's a generalized iterator-based version:
def ifill(default, *iterables):
from itertools import repeat
nextfuncs = [iter(iterable).next for iterable in iterables]
# how many non-exhausted iterators are left
num_left = [len(iterables)]
# closure for iterating over the next value of each iterator
def iter_next_tuple_values():
for i,next in enumerate(nextfuncs):
try: yield next()
except StopIteration:
num_left[0] -= 1
nextfuncs[i] = next = repeat(default).next
yield next()
while True:
t = tuple(iter_next_tuple_values())
if not num_left[0]:
break
yield t
# example
lista = ['a1', 'a2']
listb = ['b10', 'b11', 'b12', 'b13']
for iterables in [
(lista, listb),
(lista, listb, ()),
((), listb, ()),
((), (), ())
]:
print list(ifill(None, *iterables)) == map(None, *iterables)
George
More information about the Python-list
mailing list