【问题标题】:Delete items from nested dict recursively递归地从嵌套字典中删除项目
【发布时间】:2017-12-13 01:45:07
【问题描述】:

对不起,我做错了什么?

我有嵌套的 dict,我希望将其转储到 json 中。

[{'text': 'Root', 'children': [{'text': 'X', 'children': [None, None], 'id': 2}, {'text': 'Y', 'children': [], 'id': 3}], 'id': 1}]

我需要从中删除所有“无”值。这是我的代码:

for items in sub_tree_dicts:
    del_null(items['children'])

def del_null(childrens):
    for child in childrens:
        if child is None:
            childrens.remove(child)
        else:
            del_null(child['children'])

不幸的是,代码没有按预期工作,只从列表中删除第一个“无”。我哪里错了?

谢谢。

【问题讨论】:

  • 在迭代字典时不要修改字典。您的 childrens.remove(child) 正在破坏您的 for 循环。
  • 您知道当您想转换为 JSON 时不需要删除 None,因为 json.dumps() 会将其修改为 null...?
  • @juanpa.arrivillaga:你是对的。我已经更正了我的评论。
  • 想一想当您删除 None 时会发生什么,就像您尝试删除 [None, None, 42] 之类的东西一样

标签: python recursion


【解决方案1】:

在迭代列表时不应修改字典/列表/等。您可以中断引用,使循环不知道去哪里。

我相当肯定有更好的方法,但我会在不过多修改代码的情况下这样做:

for items in sub_tree_dicts:
    del_null(items['children'])

def del_null(childrens):
    invalid_children = []
    for child in childrens:
        if child is None:
            invalid_children.append(child)
        else:
            del_null(child['children'])
    for child in invalid_children:
        childrens.remove(child)

【讨论】:

    【解决方案2】:

    你可以试试这个:

    s = [{'text': 'Root', 'children': [{'text': 'X', 'children': [None, None], 'id': 2}, {'text': 'Y', 'children': [], 'id': 3}], 'id': 1}]
    d = {}
    def filter_none(s, last=None):
       if last:
           new_list = [{a:[i for i in b if i is not None] if isinstance(b, list) else b for a, b in c.items()} for c in s]
           return new_list
       for a, b in s.items():
          if not isinstance(b, list):
             d[a] = b
          else:
             d[a] = filter_none(b, last=a)
    
    filter_none(s[0])
    new_d = [d]
    

    输出:

    [{'text': 'Root', 'children': [{'text': 'X', 'children': [], 'id': 2}, {'text': 'Y', 'children': [], 'id': 3}], 'id': 1}]
    

    【讨论】:

    • 好男爵。我知道您可能在这里追求效率,但我是一位经验丰富的 python 用户,而且这里的可读性非常粗糙,甚至需要我一段时间才能弄清楚 xD 发生了什么。
    猜你喜欢
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 2016-02-05
    • 2021-11-01
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    相关资源
    最近更新 更多