Delete dict and subdict items of some name

Oscar Benjamin oscar.j.benjamin at gmail.com
Mon Dec 17 18:44:53 EST 2012


On 17 December 2012 23:08, MRAB <python at mrabarnett.plus.com> wrote:
> On 2012年12月17日 22:00, Dave Angel wrote:
>> On 12/17/2012 04:33 PM, Mitya Sirenef wrote:
>>> On 12/17/2012 01:30 PM, Tim Chase wrote:
>>>> On 12/17/12 11:43, Mitya Sirenef wrote:
>>>>> On 12/17/2012 12:27 PM, Gnarlodious wrote:
>>>>>>>>>>>> Hello. What I want to do is delete every dictionary key/value
>>>>>> of the name 'Favicon' regardless of depth in subdicts, of which
>>>>>> there are many. What is the best way to do it?
>>>>>>>>>> Something like this should work:
>>>>>>>>>> def delkey(d, key):
>>>>> if isinstance(d, dict):
>>>>> if key in d: del d[key]
>>>>> for val in d.values():
>>>>> delkey(val, key)
>>>>>>>> Unless you have something hatefully recursive like
>>>>>>>> d = {}
>>>> d["hello"] = d
>>>>>>>> :-)
>>>>>>>>> True -- didn't think of that..!
>>>>>> I guess then adding a check 'if val is not d: delkey(val, key)'
>>> would take care of it?
>>>>> No, that would only cover the self-recursive case. If there's a dict
>> which contains another one, which contains the first, then the recursion
>> is indirect, and much harder to check for.
>>>> Checking reliably for arbitrary recursion patterns is tricky, but
>> do-able. Most people degenerate into just setting an arbitrary max
>> depth. But I can describe two approaches to this kind of problem.
>>> Wouldn't a set of the id of the visited objects work?

Of course it would. This is just a tree search.
Here's a depth-first-search function:
def dfs(root, childfunc, func):
 '''depth first search on a tree
 calls func(node) once for each node'''
 visited = set()
 visiting = OrderedDict()
 visiting[id(root)] = it = iter([root])
 while True:
 try:
 node = next(it)
 except StopIteration:
 try:
 node, it = visiting.popitem()
 except KeyError:
 return
 key = id(node)
 if isinstance(node, dict) and key not in visited:
 func(node)
 visiting[key] = it = iter(childfunc(node))
 visited.add(key)
Now you can do:
dfs(my_dict_tree, lambda x: x.pop('Favicon', None))
Although I wouldn't bother with the above unless I had some reason to
expect possible cycles.
Oscar


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /