flattening a dict

Arnaud Delobelle arnodel at googlemail.com
Sun Feb 17 18:15:12 CET 2008


On Feb 17, 4:03 pm, Boris Borcic <bbor... at gmail.com> wrote:
> George Sakkis wrote:
> > On Feb 17, 7:51 am, Arnaud Delobelle <arno... at googlemail.com> wrote:
>
> >> BTW, I keep using the idiom itertools.chain(*iterable).  I guess that
> >> during function calls *iterable gets expanded to a tuple.  Wouldn't it
> >> be nice to have an equivalent one-argument function that takes an
> >> iterable of iterables and return the 'flattened' iterable?
>
> > Indeed; I don't have any exact numbers but I roughly use this idiom as
> > often or more as the case where chain() takes a known fixed number of
> > arguments. The equivalent function you describe is trivial:
>
> > def chain2(iter_of_iters):
> >   for iterable in iter_of_iters:
> >      for i in iterable:
> >         yield i
>
> or fwiw
>
> chainstar = lambda iters : (x for it in iters for x in it)
>
> - a form that better suggests how to inline it in the calling expression, if
> applicable.

Indeed:

def flattendict(d):
    def gen(d, pfx=()):
        return (x for k, v in d.iteritems()
                for x in (gen(v, pfx+(k,)) if isinstance(v, dict)
                          else ((pfx+(k,), v),)))
    return dict(gen(d))

I don't know, I find the chain(*...) version more readable, although
this one is probably better.  Please, Mr itertools, can we have
chainstar?

--
Arnaud




More information about the Python-list mailing list