我有一个简单的数据结构,大致如下,具有任意深度:
# 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 ...
该问题缺少一些重要的细节,例如如何从多个中选择一个“更多”项目(示例结构中也未提及“块”,但是可以在所需的方向上扩展以下内容:] >
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': []} ]} ] }
这不使用任何单独的遍历功能。
怎么样:
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)