사전 키 이름 바꾸기
새 이름에 값을 재할당하거나 이전 이름 키를 제거하거나 dict 키/값을 반복하지 않고 사전 키의 이름을 변경할 수 있는 방법이 있습니까?
OrderedDict의 경우 해당 키의 위치를 유지하면서 동일한 작업을 수행합니다.
일반 딕트의 경우 다음을 사용할 수 있습니다.
mydict[k_new] = mydict.pop(k_old)
다음 경우를 제외하고 항목을 dict의 끝으로 이동합니다.k_new
는 이미 존재하며, 이 경우 값을 덮어씁니다.
순서를 추가로 유지하고 싶은 Python 3.7+ dict의 경우, 가장 간단한 것은 완전히 새로운 인스턴스를 재구축하는 것입니다.예를 들어, 키 이름 변경2
로.'two'
:
>>> 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())
질문에서 요구하는 바와 같이 키 자체를 수정하는 것은 비현실적입니다.이는 보통 키가 불변하고 수정할 수 없음을 의미합니다.
다음에 대한 체크 사용newkey!=oldkey
다음과 같이 할 수 있습니다.
if newkey!=oldkey:
dictionary[newkey] = dictionary[oldkey]
del dictionary[oldkey]
모든 사전 키의 이름을 변경하는 경우:
target_dict = {'k1':'v1', 'k2':'v2', 'k3':'v3'}
new_keys = ['k4','k5','k6']
for key,n_key in zip(target_dict.keys(), new_keys):
target_dict[n_key] = target_dict.pop(key)
Raymond Hettinger에 의해 쓰여진 이 글을 사용하여 수정하여 추가 할 수 있습니다.rename
이 방법은 복잡성이 O(N)가 됩니다.
def rename(self,key,new_key):
ind = self._keys.index(key) #get the index of old key, O(N) operation
self._keys[ind] = new_key #replace old key with new key in self._keys
self[new_key] = self[key] #add the new key, this is added at the end of self._keys
self._keys.pop(-1) #pop the last item in self._keys
예:
dic = OrderedDict((("a",1),("b",2),("c",3)))
print dic
dic.rename("a","foo")
dic.rename("b","bar")
dic["d"] = 5
dic.rename("d","spam")
for k,v in dic.items():
print k,v
출력:
OrderedDict({'a': 1, 'b': 2, 'c': 3})
foo 1
bar 2
c 3
spam 5
저 전에 몇 분께서....pop
원라이너에서 키를 삭제하고 작성하는 트릭입니다.
저는 개인적으로 보다 명확한 구현이 더 읽기 쉽다고 생각합니다.
d = {'a': 1, 'b': 2}
v = d['b']
del d['b']
d['c'] = v
위의 코드가 반환됩니다.{'a': 1, 'c': 2}
다른 대답들은 꽤 좋습니다.그러나 python3.6에서는 일반 dict에도 순서가 있습니다.그래서 정상적인 경우에는 키의 위치를 유지하는 것이 어렵습니다.
def rename(old_dict,old_name,new_name):
new_dict = {}
for key,value in zip(old_dict.keys(),old_dict.values()):
new_key = key if key != old_name else new_name
new_dict[new_key] = old_dict[key]
return new_dict
키 k3의 이름을 k4로 변경한다고 가정합니다.
temp_dict = {'k1':'v1', 'k2':'v2', 'k3':'v3'}
temp_dict['k4']= temp_dict.pop('k3')
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}
주의할 필요가 있을 것 같습니다.print
ipython 콘솔/노트북이 사전을 선택한 순서대로 표시...
모든 키의 이름을 한 번에 변경하려는 경우 새 이름이 포함된 목록을 제공합니다.
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()}
원본 사전을 음소거하지 않는 이 기능을 생각해 냈습니다.이 기능은 사전 목록도 지원합니다.
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))
키의 이름을 변경할 때 위의 @wim의 답변을 dict.pop()과 함께 사용하고 있는데 gotcha를 찾았습니다.이전 키 목록을 dict 인스턴스에서 완전히 분리하지 않고 키를 변경하기 위해 dict를 순환하면 새 키가 순환되고 루프가 변경되어 기존 키가 손실됩니다.
우선, 저는 이렇게 했습니다.
for current_key in my_dict:
new_key = current_key.replace(':','_')
fixed_metadata[new_key] = fixed_metadata.pop(current_key)
이런 식으로 딕트를 반복하면서 사전은 새 키, 즉 내가 바꾼 키를 찾지 말아야 할 때에도 계속해서 키를 찾아낸다는 것을 알게 되었다.(a) for loop에서 변경된 키를 찾지 않기 위해 (b) 루프 내에서 찾을 수 없는 키를 찾기 위해 인스턴스를 서로 완전히 분리해야 했습니다.
지금 하고 있는 중입니다.
current_keys = list(my_dict.keys())
for current_key in current_keys:
and so on...
my_dict.keys()를 목록으로 변환하는 것은 변경되는 dict에 대한 참조를 없애기 위해 필요했습니다.my_dict.keys()를 사용하는 것만으로, 이상한 부작용과 함께 원래의 인스턴스에 묶이게 되었습니다.
@helloswift123 당신의 기능이 마음에 듭니다.다음으로 1개의 콜에서 여러 키의 이름을 변경하기 위한 변경을 나타냅니다.
def rename(d, keymap):
"""
:param d: old dict
:type d: dict
:param keymap: [{:keys from-keys :values to-keys} keymap]
:returns: new dict
:rtype: dict
"""
new_dict = {}
for key, value in zip(d.keys(), d.values()):
new_key = keymap.get(key, key)
new_dict[new_key] = d[key]
return new_dict
다음 코드를 사용할 수 있습니다.
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
.NewKey
가 에 하지 않는OldKey
'붙입니다.
예:
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}
위의 스레드에서 몇 가지 답변을 조합하여 아래의 해결책을 제시합니다.단순하지만 사전에서 보다 복잡한 키 업데이트를 수행하기 위한 구성 요소로 사용할 수 있습니다.
test_dict = {'a': 1, 'b': 2, 'c': 3}
print(test_dict)
# {'a': 1, 'b': 2, 'c': 3}
prefix = 'up'
def dict_key_update(json_file):
new_keys = []
old_keys = []
for i,(key,value) in enumerate(json_file.items()):
old_keys.append(key)
new_keys.append(str(prefix) + key) # i have updated by adding a prefix to the
# key
for old_key, new_key in zip(old_keys,new_keys):
print('old {}, new {}'.format(old_key, new_key))
if new_key!=old_key:
json_file[new_key] = json_file.pop(old_key)
return json_file
test_dict = dict_key_update(test_dict)
print(test_dict)
# {'upa': 1, 'upb': 2, 'upc': 3}
언급URL : https://stackoverflow.com/questions/16475384/rename-a-dictionary-key
'sourcecode' 카테고리의 다른 글
hg mercurial 명령어 사용 시 "ERROR:root:code for hash md5"가 발견되지 않음 (0) | 2022.09.25 |
---|---|
mysql이 원격 연결을 설정할 수 없습니다. (0) | 2022.09.25 |
Javascript는 PHP 폭발()에 상당합니다. (0) | 2022.09.25 |
PHP를 사용하여 JSON용 어레이를 만드는 방법 (0) | 2022.09.24 |
정수를 선행 0 문자열로 포맷하는 가장 좋은 방법? (0) | 2022.09.24 |