【发布时间】:2022-08-22 01:29:45
【问题描述】:
我遇到了 Python 嵌套字典的奇怪行为。当上键为global 时,我想更新嵌套字典中的键var_set。但它会递归更新所有var_set,即使上键是foo 和bar。
g = \'global\'
s = set()
space = {g:
{\'parent\': \'None\', \'var_set\': s, \'child_dict\': {}
}
}
def create(child, parent, space):
if parent in space.keys():
space[parent][\'child_dict\'][child] = {
\'parent\': parent, \'var_set\': s, \'child_dict\': {}}
else:
create(child, parent, space[g][\'child_dict\'])
def adding(parent, var, space):
for (k, v) in space.items():
if k == parent:
v[\'var_set\'].add(var)
create(\'foo\', \'global\', space)
create(\'bar\', \'foo\', space)
print(space)
adding(g, \'a\', space)
print(space)
返回:
{\'global\': {\'parent\': \'None\', \'var_set\': set(), \'child_dict\': {\'foo\': {\'parent\': \'global\',
\'var_set\': set(), \'child_dict\': {\'bar\': {\'parent\': \'foo\', \'var_set\': set(), \'child_dict\': {}}}}}}}
{\'global\': {\'parent\': \'None\', \'var_set\': {\'a\'}, \'child_dict\': {\'foo\': {\'parent\': \'global\',
\'var_set\': {\'a\'}, \'child_dict\': {\'bar\': {\'parent\': \'foo\', \'var_set\': {\'a\'}, \'child_dict\': {}}}}}}}
为什么所有var_set 都会递归更新?我只需要更新第一个。
好吧,让我们用空集复制第一个结果并调用adding 反对它:
create(\'foo\', \'global\', space)
create(\'bar\', \'foo\', space)
lst = {\'global\': {\'parent\': \'None\', \'var_set\': set(), \'child_dict\': {\'foo\': {\'parent\': \'global\',
\'var_set\': set(), \'child_dict\': {\'bar\': {\'parent\': \'foo\', \'var_set\': set(), \'child_dict\': {}}}}}}}
print(lst == space)
adding(g, \'a\', lst)
adding(g, \'a\', space)
print(lst)
print(space)
它返回:
True
{\'global\': {\'parent\': \'None\', \'var_set\': {\'a\'}, \'child_dict\': {\'foo\': {\'parent\': \'global\',
\'var_set\': set(), \'child_dict\': {\'bar\': {\'parent\': \'foo\', \'var_set\': set(), \'child_dict\': {}}}}}}}
{\'global\': {\'parent\': \'None\', \'var_set\': {\'a\'}, \'child_dict\': {\'foo\': {\'parent\': \'global\',
\'var_set\': {\'a\'}, \'child_dict\': {\'bar\': {\'parent\': \'foo\', \'var_set\': {\'a\'}, \'child_dict\': {}}}}}}}
它们是相等的并且给出不同的结果。为什么会有这样的分歧?如何让它只更新global\'s var_set 而忽略foo\'s 和bar\'s ?
更新:
问题在于为var_sets 全局声明空集。它们链接到一个对象。更改一次将更改为var_sets。
-
为什么你只创建一个集合并在每个字典中使用它?只需将
s = set()和\'var_set\' : s移动到\'var_set\' : set()(我也建议在与其他人共享您的代码之前阅读PEP 8)。 -
它应该支持多达 20 级嵌套(您处于此限制的 1/3),但它变得难以辨认,因此错误更快......考虑使用
pprint使其更具可读性,例如 JSON。
标签: python dictionary nested