如何在dict / list数据结构的“级别”插入? -{'foo':'bar','more':[{'foo':None}]}

问题描述 投票:0回答:2

我有一个简单的数据结构,大致如下,具有任意深度:

# Level 0
{ 'foo': 'bar', 'more': 
  [   # Level 1
      { 'foo': 'can', 'more': [    # Level 2
                                   { 'foo': 'haz', 'more': [] }
                              ]
      },
      { 'foo': 'baz', 'more': [    # Level 2
                                   { 'foo': None, 'more': [] }
                              ]
      }
  ]
}

正在处理要在某个级别插入的功能。如果foo值为None,则插入value,否则插入一个新的“兄弟”,即同一级别的新dict。除了第0级,所有内容都在list内,因此应该是append


尝试:

def traverse_to_level(obj, level):
    if obj['_level'] == level:
        return obj

    for _obj in obj['block']:
        found = traverse_to_level(_obj, level)
        if found is not None:
            return found

    return None


def set_obj(top_obj, value, level):
    obj = traverse_to_level(top_obj, level)
    if obj is None:
        directive = traverse_to_level(top_obj, level - 1)
    assert obj is not None
    if obj['foo'] is None:
        obj['foo'] = value
    elif obj['_level'] < level:
        obj['more'].append({'foo': value, 'more': [], '_level': level})
    else:
        obj = traverse_to_level(top_obj, level - 1)
        obj['more'].append({'foo': value, 'more': [], '_level': level})

    return obj

遍历这样的结构并通过level进行就地更新的正确方法是什么?

我有一个简单的数据结构,大致如下,具有任意深度:#Level 0 {'foo':'bar','more':[#Level 1 {'foo':'can','more' :[#Level 2 ...

python list dictionary nested traversal
2个回答
0
投票

该问题缺少一些重要的细节,例如如何从多个中选择一个“更多”项目(示例结构中也未提及“块”,但是可以在所需的方向上扩展以下内容:] >

example = {
    'foo': 'bar',
    'more':
        [  # Level 1
            {
                'foo': 'can',
                'more': [  # Level 2
                    {
                        'foo': 'haz',
                        'more': []}
                ]
            },
            {
                'foo': 'baz',
                'more': [  # Level 2
                    {
                        'foo': None,
                        'more': []
                    }
                ]
            }
        ]
}


def set_obj_at_level(top_obj, value, level, current_level=1):
    if top_obj["foo"] is None:
        top_obj["foo"] = value
        return top_obj

    if level <= current_level or len(top_obj.get("more", [])) == 0:
        top_obj.setdefault("more", []).append({'foo': value, 'more': []})
    else:
        set_obj_at_level(top_obj["more"][0], value, level, current_level + 1)

    return top_obj


pprint(set_obj_at_level(example, "123", 2))

res = {
    'foo': 'bar',
    'more': [
        {
            'foo': 'can',
            'more': [
                {'foo': 'haz', 'more': []},
                {'foo': '123', 'more': []}
            ]},
        {
            'foo': 'baz',
            'more': [
                {'foo': None, 'more': []}
            ]}
    ]
}

这不使用任何单独的遍历功能。


0
投票

怎么样:

def set_obj(top_obj, value, level):
    if level == 1:
        more = top_obj['more']
        hasnt_none = True
        for n in more:
            if n['foo'] is None:
                n['foo'] = value
                hasnt_none = False
        if hasnt_none:
            more.append({'foo': value, 'more': []})
    else:
        for n in top_obj['more']:
            set_obj(n, value, level-1)
© www.soinside.com 2019 - 2024. All rights reserved.