recursive function: use a global or pass a parameter?

Rustom Mody rustompmody at gmail.com
Fri Jan 16 19:22:09 CET 2015


On Friday, January 16, 2015 at 11:26:46 PM UTC+5:30, Chris Angelico wrote:
> On Sat, Jan 17, 2015 at 4:49 AM, Tim  wrote:
> > I want to get a union of all the values that any 'things' key may have, even in a nested dictionary (and I do not know beforehand how deep the nesting might go):
> >
> > d = {'things':1, 'two':{'things':2}}
> >
> > def walk(obj, res):
> >     if not hasattr(obj, 'keys'):
> >         return set(), set()
> >
> >     if 'things' in obj:
> >         res.add(obj['things'])
> >
> >     for k in obj:
> >         walk(obj[k], res)
> >
> >     return res
> >
> > walk(d, set()) # returns {1, 2}
> >
> > Is it better to use a global to keep track of the values or does it even matter?
> 
> I would use a parameter rather than a global, but I'd make the
> parameter optional:
> 
> def all_keys(obj, accum=None):
>     if accum is None: accum=set()
>     if 'things' in obj:
>         res.add(obj['things'])
>     for val in obj.values():
>         all_keys(val, accum)
>     return all_keys
> 
> ChrisA

I dont like the hardwired this. However keeping that...

def all_keys(obj):
    if   not isinstance(obj, type({})): return set()

    return ((set([obj['things']]) if 'things' in obj else set())   |
               set(v for s in obj.values() for v in all_keys(s)))



More information about the Python-list mailing list