我有一个字典,其中包含字典,而字典可能会无限地包含字典。我想更改所有字典中的每个键,但映射到其中一个嵌套字典的键除外。我知道密钥是不可变的,我想做的事情是这样的:
layer[item + '_addition'] = layer.pop(item)
我现在拥有的是:
def alterKeys(item, layer=topLevelDict):
if isinstance(item, dict):
for i in item:
alterKeys(item[i], item)
else:
layer[item + '_addition'] = layer.pop(item)
这不起作用,因为它会不断地递归到树中,直到最后一行尝试从dict中弹出一个值,而不是一个键,这会引发一个KeyError。 我知道我已经接近解决方案,但我已经考虑了几分钟而且我似乎无法弄明白。
答案 0 :(得分:1)
在写这个问题时,我想出来了。我想我会发布这个以防其他人在某些时候有同样的问题。
def alterKeys(item, layer=topLevelDict, key=None):
if isinstance(item, dict):
for k, v in item.items():
alterKeys(v, item, k)
elif isinstance(key, str):
layer[key + '_addition'] = layer.pop(key)
如果有人有更优雅或更好的解决方案,我很乐意看到它。我刚刚通过它运行一个json文件测试了这个脚本,它重命名了没有映射到字典的每个键,这正是我想要的。
如果我希望重命名每个键,包括那些映射到嵌套词典的键,我可以使用这个代码:
def alterKeys(item, layer=topLevelDict, key=None):
if isinstance(item, dict):
for k, v in item.items():
alterKeys(v, item, k)
if isinstance(key, str):
layer[key + '_addition'] = layer.pop(key)
如果您使用的是python2,请记住使用.iteritems()而不是.items(),并使用isinstance(key,basestring)而不是isinstance(key,str)。
答案 1 :(得分:0)
我在寻找一个解决方案时遇到了这个问题,所以我想我会发布自己的python 3.7.4解决方案。
以下代码将迭代对象,该对象是有序dict和list的嵌套组合,并且以下代码会将名为@index
的所有字段重命名为id
。
from collections import OrderedDict
def rename_index_to_id(iterable):
if type(iterable) is OrderedDict:
for key in list(iterable.keys()):
if key == "@index":
iterable["id"] = iterable["@index"]
del iterable[key]
for obj in iterable:
rename_index_to_id(iterable[obj])
elif type(iterable) is list:
for obj in iterable:
rename_index_to_id(obj)
答案 2 :(得分:0)
我修改了@solution 中的 martin-riddar 以使其更通用。
from collections import OrderedDict
def rename_dict_key(the_dict, old_key_name, new_key_name):
if type(the_dict) in [dict, OrderedDict]:
for key in list(the_dict.keys()):
if key == old_key_name:
the_dict[new_key_name] = the_dict[old_key_name]
del the_dict[key]
for obj in the_dict:
rename_dict_key(the_dict[obj], old_key_name, new_key_name)
elif type(the_dict) is list:
for obj in the_dict:
rename_dict_key(obj, old_key_name, new_key_name)
注意:我使用 dict
而不是 OrderedDict
对此进行了测试,但我认为结果不会有任何不同。