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