gpt4 book ai didi

Python:搜索和删除嵌套的字典列表

转载 作者:太空狗 更新时间:2023-10-30 02:47:49 25 4
gpt4 key购买 nike

我有一个嵌套列表和字典树,我需要递归地遍历并删除符合特定条件的整个字典。例如,我需要删除所有“类型”为“文件夹”且没有子项(或空的子项列表)的词典。

我还是一个初学者 Pythonist,所以请原谅我的蛮力。

这是一个示例字典,其格式便于复制和粘贴。

{'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)

最佳答案

我建议您编写一个函数来遍历您的数据结构并在每个节点上调用一个函数。

已更新以避免“从迭代序列​​中删除项目”错误

例如

def walk(node,parent=None,func=None):
for child in list(node.get('children',[])):
walk(child,parent=node,func=func)
if func is not None:
func(node,parent=parent)

def removeEmptyFolders(node,parent):
if node.get('type') == 'Folder' and len(node.get('children',[])) == 0:
parent['children'].remove(node)

d = {'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'}

注意事项

  • Walk 函数使用三个参数,子节点、父节点和work 函数。
  • walk 函数在访问子节点后调用work 函数。
  • work 函数将子节点和父节点都作为参数,因此修剪子节点就像 parent['children'].remove(child) 一样简单
  • 更新:如评论中所述,如果您在迭代时从序列中删除,它将跳过元素。 for child in list(node.get('children',[]))walk 函数中复制子列表,允许从父键中删除条目不跳过。

然后:

>>> walk(d,func=removeEmptyFolders)
>>> from pprint import pprint
>>> pprint(d)
{'children': [{'children': [{'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'}

关于Python:搜索和删除嵌套的字典列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15723630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com