是否有一种方法重命名字典键,而不重新分配其值为一个新名称和删除旧的名称键;并且没有通过dict键/值迭代?
在OrderedDict的情况下,做同样的事情,同时保持该键的位置。
是否有一种方法重命名字典键,而不重新分配其值为一个新名称和删除旧的名称键;并且没有通过dict键/值迭代?
在OrderedDict的情况下,做同样的事情,同时保持该键的位置。
当前回答
如果有人想要一次重命名所有的键,提供一个包含新名称的列表:
def rename_keys(dict_, new_keys):
"""
new_keys: type List(), must match length of dict_
"""
# dict_ = {oldK: value}
# d1={oldK:newK,} maps old keys to the new ones:
d1 = dict( zip( list(dict_.keys()), new_keys) )
# d1{oldK} == new_key
return {d1[oldK]: value for oldK, value in dict_.items()}
其他回答
Python 3.6(以后?)我会用下面的一句话
test = {'a': 1, 'old': 2, 'c': 3}
old_k = 'old'
new_k = 'new'
new_v = 4 # optional
print(dict((new_k, new_v) if k == old_k else (k, v) for k, v in test.items()))
生产
{'a': 1, 'new': 4, 'c': 3}
可能值得注意的是,如果没有打印语句,ipython控制台/jupyter笔记本将按照它们选择的顺序显示字典…
我想出了这个函数,它不会改变原来的字典。这个函数也支持字典列表。
import functools
from typing import Union, Dict, List
def rename_dict_keys(
data: Union[Dict, List[Dict]], old_key: str, new_key: str
):
"""
This function renames dictionary keys
:param data:
:param old_key:
:param new_key:
:return: Union[Dict, List[Dict]]
"""
if isinstance(data, dict):
res = {k: v for k, v in data.items() if k != old_key}
try:
res[new_key] = data[old_key]
except KeyError:
raise KeyError(
"cannot rename key as old key '%s' is not present in data"
% old_key
)
return res
elif isinstance(data, list):
return list(
map(
functools.partial(
rename_dict_keys, old_key=old_key, new_key=new_key
),
data,
)
)
raise ValueError("expected type List[Dict] or Dict got '%s' for data" % type(data))
如果有人想要一次重命名所有的键,提供一个包含新名称的列表:
def rename_keys(dict_, new_keys):
"""
new_keys: type List(), must match length of dict_
"""
# dict_ = {oldK: value}
# d1={oldK:newK,} maps old keys to the new ones:
d1 = dict( zip( list(dict_.keys()), new_keys) )
# d1{oldK} == new_key
return {d1[oldK]: value for oldK, value in dict_.items()}
我使用@wim的答案上面,dict.pop()重命名键时,但我发现了一个问题。循环遍历dict以更改键,而没有将旧键列表与dict实例完全分离,结果将新的、已更改的键循环到循环中,并丢失一些现有的键。
首先,我是这样做的:
for current_key in my_dict:
new_key = current_key.replace(':','_')
fixed_metadata[new_key] = fixed_metadata.pop(current_key)
我发现,以这种方式循环字典,字典一直在找到键,即使它不应该,也就是说,新的键,我已经改变的那些!我需要将实例彼此完全分开,以(a)避免在for循环中找到我自己更改的键,以及(b)找到由于某种原因在循环中没有找到的一些键。
我现在正在做这件事:
current_keys = list(my_dict.keys())
for current_key in current_keys:
and so on...
必须将my_dict.keys()转换为列表,以摆脱对不断变化的dict的引用。仅使用my_dict.keys()将我与原始实例绑定在一起,并产生奇怪的副作用。
你可以使用下面的代码:
OldDict={'a':'v1', 'b':'v2', 'c':'v3'}
OldKey=['a','b','c']
NewKey=['A','B','C']
def DictKeyChanger(dict,OldKey,NewKey):
ListAllKey=list(dict.keys())
for x in range(0,len(NewKey)):
dict[NewKey[x]]=dict[OldKey[x]] if OldKey[x] in ListAllKey else None
for x in ListAllKey:
dict.pop(x)
return dict
NewDict=DictKeyChanger(OldDict,OldKey,NewKey)
print(NewDict)#===>>{'A': 'v1', 'B': 'v2', 'C': 'v3'}
注:
列表OldKey和列表NewKey的长度必须相等。 列表OldKey的长度必须等于listNewKey,如果该键在OldKey中不存在,则将'noexis'改为如下所示。
例子:
OldDict={'a':'v1', 'b':'v2', 'c':'v3'}
OldKey=['a','b','c','noexis','noexis']
NewKey=['A','B','C','D','E']
NewDict=DictKeyChanger(OldDict,OldKey,NewKey)
print(NewDict)#===>>{'A': 'v1', 'B': 'v2', 'C': 'v3', 'D': None, 'E': None}