是否有一种方法重命名字典键,而不重新分配其值为一个新名称和删除旧的名称键;并且没有通过dict键/值迭代?
在OrderedDict的情况下,做同样的事情,同时保持该键的位置。
是否有一种方法重命名字典键,而不重新分配其值为一个新名称和删除旧的名称键;并且没有通过dict键/值迭代?
在OrderedDict的情况下,做同样的事情,同时保持该键的位置。
当前回答
我想出了这个函数,它不会改变原来的字典。这个函数也支持字典列表。
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))
其他回答
你可以使用下面的代码:
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}
使用newkey检查!=oldkey,这样你可以做:
if newkey!=oldkey:
dictionary[newkey] = dictionary[oldkey]
del dictionary[oldkey]
我想出了这个函数,它不会改变原来的字典。这个函数也支持字典列表。
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))
对于一个普通的字典,你可以使用:
mydict[k_new] = mydict.pop(k_old)
这将把项移动到dict的末尾,除非k_new已经存在,在这种情况下,它将覆盖原地的值。
对于Python 3.7+字典,您还想保留顺序,最简单的方法是重新构建一个全新的实例。例如,将键2重命名为' 2 ':
>>> d = {0:0, 1:1, 2:2, 3:3}
>>> {"two" if k == 2 else k:v for k,v in d.items()}
{0: 0, 1: 1, 'two': 2, 3: 3}
OrderedDict也是如此,不能使用dict理解语法,但可以使用生成器表达式:
OrderedDict((k_new if k == k_old else k, v) for k, v in od.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笔记本将按照它们选择的顺序显示字典…