[英]How to rename keys in a python dictionary of dictionaries with arbitrary depth
我有一本字典,其中包含字典,而字典又可能包含无穷无尽的字典。 我想更改所有字典中的每个键,但映射到嵌套字典之一的键除外。 我知道密钥是不可变的,我想做这样的事情:
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)
这是行不通的,因为它会不断地沿着树向下递归,直到最后一行尝试从字典中弹出一个值,而不是一个键,这会引发 KeyError。 我知道我已经接近解决方案了,但是我已经考虑了几分钟,但似乎无法弄清楚。
在写这个问题时,我想通了。 我想我会发布这个以防其他人在某个时候有同样的问题。
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)。
我在寻找这个问题的一个轻微变体的解决方案时遇到了这个问题,所以我想我会发布我自己的 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)
我修改了@ 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
对此进行了测试,尽管我不希望结果会有所不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.