【发布时间】:2013-03-21 08:35:21
【问题描述】:
我有一个嵌套列表和字典树,我需要递归地遍历并删除符合特定条件的整个字典。例如,我需要删除所有“类型”为“文件夹”且没有子级(或空的子级列表)的字典。
我仍然是 Python 初学者,所以请原谅我的蛮力。
这是一个示例字典,其格式便于复制和粘贴。
{'children': [{'children': [{'key': 'group-1',
'name': 'PRD',
'parent': 'dc-1',
'type': 'Folder'},
{'children': [{'key': 'group-11',
'name': 'App1',
'parent': 'group-2',
'type': 'Folder'}],
'key': 'group-2',
'name': 'QA',
'parent': 'dc-1',
'type': 'Folder'},
{'key': 'group-3',
'name': 'Keep',
'parent': 'dc-1',
'type': 'Host'}],
'key': 'dc-1',
'name': 'ABC',
'parent': 'root',
'type': 'Datacenter'}],
'key': 'root',
'name': 'Datacenters',
'parent': None,
'type': 'Folder'}
在这本字典中,唯一应该保留的树是 /root/dc-1/group-3。应先删除 group-11 文件夹,然后删除其父文件夹(因为子文件夹已不存在),等等。
我尝试了许多不同的递归方法,但似乎无法使其正常工作。任何帮助将不胜感激。
def cleanup(tree):
def inner(tree):
if isinstance(tree, dict):
if 'type' in tree and tree['type'] == 'Folder':
if 'children' not in tree or not tree['children']:
print 'Deleting tree: ' + str(tree['name'])
if str(tree['key']) not in del_nodes:
del_nodes.append(str(tree['key']))
else:
for item in tree.values():
inner(item)
# Delete empty folders here
if del_nodes:
print 'Perform delete here'
if 'children' in tree and isinstance(tree['children'], (list, tuple)):
getvals = operator.itemgetter('key')
tree['children'].sort(key=getvals)
result = []
# groupby is the wrong method. I need a list of tree['children'] that doesn't contain keys in del_nodes
for k, g in itertools.groupby(tree['children'], getvals):
result.append(g.next())
tree['children'][:] = result
del_nodes = []
else:
for item in tree.values():
inner(item)
elif isinstance(tree, (list, tuple)):
for item in tree:
inner(item)
if isinstance(item, dict):
if 'type' in item and item['type'] == 'Folder':
if 'children' not in item or not item['children']:
print 'Delete ' + str(item['name'])
if str(item['key']) not in del_nodes:
del_nodes.append(str(item['key']))
elif isinstance(item, (list, tuple)):
if not item:
print 'Delete ' + str(item['name'])
if str(item['key']) not in del_nodes:
del_nodes.append(str(item['key']))
inner(tree)
【问题讨论】:
-
1) 你不需要
isinstance,如果你能从dict的type属性中算出来的话; 2) 在 Python 中,习惯上“请求宽恕,而不是许可”,这意味着在访问之前检查内容是否在 dict 中是不好的风格——它会使代码混乱并创建不必要的嵌套级别。你应该抓住KeyError。同样,这可能会因为不是一个真正的问题而被关闭——您没有指定问题,基本上只是要求我们编写您的代码。 -
1) 感谢您的建议。将来我将使用 try 块而不是测试键的存在。 2)我认为问题很清楚。我需要删除所有没有子节点或为空子节点的节点。如果我要求其他人编写我的代码,我就不会提供我的函数并寻求帮助。
标签: python list dictionary nested