有没有一种方法可以重命名字典键,而不重新分配其值为新名称并删除旧名称的键;并且不需要迭代字典键/值?
在有序字典 OrderedDict
的情况下,保持该键的位置。
对于普通字典,您可以使用:
mydict[k_new] = mydict.pop(k_old)
k_new
已经存在,否则它将在原地覆盖该值。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
,您不能使用字典推导语法,但可以使用生成器表达式:OrderedDict((k_new if k == k_old else k, v) for k, v in od.items())
dict.pop
可用于基于OrderedDict的操作。 - DanielOrderedDict
会保留插入顺序,这并不是该问题所问的内容。 - wimfor key_old, value in list(d.items()):
中的list()
中。 - Bob Stein通过检查newkey!=oldkey
,你可以这样做:
if newkey!=oldkey:
dictionary[newkey] = dictionary[oldkey]
del dictionary[oldkey]
OrderedDict
。 - Granitosaurus如果需要重新命名所有字典键:
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)
target_dict.keys()
保证与定义中的顺序相同吗?我认为Python字典是无序的,从字典键视图中得到的顺序是不可预测的。 - ttimasdftarget_dict = dict(zip(new_keys, list(target_dict.values())))
请注意,这只是代码的一部分。 - vinodhrajfor key,n_key in zip(target_dict.keys(), new_keys): target_dict[n_key] = target_dict.pop(key)
时,即使字典被修改了,你也会得到RuntimeError:dictionary keys changed during iteration
的错误。 - GSAfor key,n_key in zip(target_dict.keys(), new_keys): target_dict[n_key] = target_dict.pop(key)
时,你会得到RuntimeError: dictionary keys changed during iteration
的错误,尽管对字典进行了更改。 - GSAOrderedDict recipe
并修改它以添加一个 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
OrderedDict
。但我建议:创建一个继承自OrderedDict
的类,并添加一个rename
方法。 - Ashwini Chaudhary在我之前有一些人提到了使用 .pop
技巧以一行代码的方式删除和创建一个键。
我个人认为更显式的实现更易读:
d = {'a': 1, 'b': 2}
v = d['b']
del d['b']
d['c'] = v
上面的代码返回{'a': 1, 'c': 2}
temp_dict = {'k1':'v1', 'k2':'v2', 'k3':'v3'}
temp_dict['k4']= temp_dict.pop('k3')
TypeError: 'dict' object is not callable
。如果你想引用 k3
键的值,那么应该使用方括号而不是圆括号。然而,这只会向字典中添加一个新键,而不会重命名现有的键,正如所请求的那样。 - Mewtwo其他回答都很好。但在Python3.6中,普通字典也具有顺序。因此,在正常情况下很难保持键的位置。
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
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控制台/Jupyter Notebook会按照它们自己的顺序呈现字典...
如果有人想要一次性重命名所有键,并提供一个包含新名称的列表:
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()}
for current_key in my_dict:
new_key = current_key.replace(':','_')
fixed_metadata[new_key] = fixed_metadata.pop(current_key)
current_keys = list(my_dict.keys())
for current_key in current_keys:
and so on...
OrderedDict
。当比较字典是否相等时,字典会忽略顺序,而OrderedDict
在比较时考虑顺序。我知道你提供了一个解释链接,但我认为你的评论可能会误导那些没有阅读该链接的人。 - Flimmdict
和OrderedDict
之间的差异,并且OrderedDict
现在已经过时。我认为,就这个问题而言,讨论这个观点也是离题的。你链接的那个问题是更好的讨论地点。有趣的是,你链接的那个问题上唯一得到赞同的答案也认为这些差异很重要,而且OrderedDict
并不过时。如果你有不同的答案,请去那里发表并让社区投票。https://dev59.com/q1UL5IYBdhLWcg3wFErw - Flimm