Tim wrote: > I have this type of situation and wonder if I should use a global variable > outside the recursive function instead of passing the updated parameter > through. > > 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?
Globals are generally bad as they make code non-reentrant; when two calls of the function run simultaneously the data will be messed up. I recommend that you use a generator: >>> def walk(obj): ... if not hasattr(obj, "keys"): ... return ... if "things" in obj: ... yield obj["things"] ... for v in obj.values(): ... yield from walk(v) ... >>> d = {'things':1, 'two':{'things':2}} >>> set(walk(d)) {1, 2} In Python before 3.3 you have to replace yield from walk(v) with a loop: for t in walk(v): yield t -- https://mail.python.org/mailman/listinfo/python-list