Python 重命名字典键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16475384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 22:45:42  来源:igfitidea点击:

Rename a dictionary key

pythondictionaryassociative-arrayordereddictionary

提问by rabin utam

Is there a way to rename a dictionary key, without reassigning its value to a new name and removing the old name key; and without iterating through dict key/value?

In case of OrderedDict, do the same, while keeping that key's position.

有没有办法重命名字典键,而无需将其值重新分配给新名称并删除旧名称键;并且不遍历 dict 键/值?

在 OrderedDict 的情况下,做同样的事情,同时保持那个键的位置。

回答by Srinivas Reddy Thatiparthy

Using a check for newkey!=oldkey, this way you can do:

使用 check for newkey!=oldkey,你可以这样做:

if newkey!=oldkey:  
    dictionary[newkey] = dictionary[oldkey]
    del dictionary[oldkey]

回答by wim

For a regular dict, you can use:

对于常规 dict,您可以使用:

mydict[new_key] = mydict.pop(old_key)

For an OrderedDict, I think you must build an entirely new one using a comprehension.

对于 OrderedDict,我认为您必须使用理解来构建一个全新的。

>>> OrderedDict(zip('123', 'abc'))
OrderedDict([('1', 'a'), ('2', 'b'), ('3', 'c')])
>>> oldkey, newkey = '2', 'potato'
>>> OrderedDict((newkey if k == oldkey else k, v) for k, v in _.viewitems())
OrderedDict([('1', 'a'), ('potato', 'b'), ('3', 'c')])

Modifying the key itself, as this question seems to be asking, is impractical because dict keys are usually immutableobjects such as numbers, strings or tuples. Instead of trying to modify the key, reassigning the value to a new key and removing the old key is how you can achieve the "rename" in python.

正如这个问题似乎在问的那样,修改键本身是不切实际的,因为 dict 键通常是不可变的对象,例如数字、字符串或元组。不是尝试修改键,而是将值重新分配给新键并删除旧键是在 python 中实现“重命名”的方法。

回答by Ashwini Chaudhary

You can use this OrderedDict recipewritten by Raymond Hettinger and modify it to add a renamemethod, but this is going to be a O(N) in complexity:

你可以使用OrderedDict recipeRaymond 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

Example:

例子:

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

output:

输出:

OrderedDict({'a': 1, 'b': 2, 'c': 3})
foo 1
bar 2
c 3
spam 5

回答by Tcll

best method in 1 line:

1行中的最佳方法:

>>> d = {'test':[0,1,2]}
>>> d['test2'] = d.pop('test')
>>> d
{'test2': [0, 1, 2]}

回答by Uri Goren

A few people before me mentioned the .poptrick to delete and create a key in a one-liner.

在我之前的一些人提到了.pop在单行中删除和创建密钥的技巧。

I personally find the more explicit implementation more readable:

我个人认为更明确的实现更具可读性:

d = {'a': 1, 'b': 2}
v = d['b']
del d['b']
d['c'] = v

The code above returns {'a': 1, 'c': 2}

上面的代码返回 {'a': 1, 'c': 2}

回答by helloswift123

Other answers are pretty good.But in python3.6, regular dict also has order. So it's hard to keep key's position in normal case.

其他答案都不错。但是在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

回答by excyberlabber

I am using @wim 's answer above, with dict.pop() when renaming keys, but I found a gotcha. Cycling through the dict to change the keys, without separating the list of old keys completely from the dict instance, resulted in cycling new, changed keys into the loop, and missing some existing keys.

我在重命名键时使用@wim 的答案,并使用 dict.pop() ,但我发现了一个问题。循环遍历 dict 来更改键,而没有将旧键列表与 dict 实例完全分开,导致将新的、更改的键循环到循环中,并丢失一些现有的键。

To start with, I did it this way:

首先,我是这样做的:

for current_key in my_dict:
    new_key = current_key.replace(':','_')
    fixed_metadata[new_key] = fixed_metadata.pop(current_key)

I found that cycling through the dict in this way, the dictionary kept finding keys even when it shouldn't, i.e., the new keys, the ones I had changed! I needed to separate the instances completely from each other to (a) avoid finding my own changed keys in the for loop, and (b) find some keys that were not being found within the loop for some reason.

我发现以这种方式循环遍历 dict 时,即使不应该,字典也会继续查找键,即新键,即我已更改的键!我需要将实例彼此完全分开,以 (a) 避免在 for 循环中找到我自己更改的键,以及 (b) 找到一些由于某种原因在循环中找不到的键。

I am doing this now:

我现在这样做:

current_keys = list(my_dict.keys())
for current_key in current_keys:
    and so on...

Converting the my_dict.keys() to a list was necessary to get free of the reference to the changing dict. Just using my_dict.keys() kept me tied to the original instance, with the strange side effects.

必须将 my_dict.keys() 转换为列表才能摆脱对不断变化的 dict 的引用。仅使用 my_dict.keys() 就让我与原始实例联系在一起,并产生奇怪的副作用。

回答by Sirmione

In case someone wants to rename all the keys at once providing a list with the new names:

如果有人想一次重命名所有键,提供一个包含新名称的列表:

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()}

回答by KeithWM

In Python 3.6 (onwards?) I would go for the following one-liner

在 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()))

which produces

产生

{'a': 1, 'new': 4, 'c': 3}

May be worth noting that without the printstatement the ipython console/jupyter notebook present the dictionary in an order of their choosing...

可能值得注意的是,如果没有print声明,ipython 控制台/jupyter 笔记本会按照他们选择的顺序显示字典......

回答by Shishir

Suppose you want to rename key k3 to k4:

假设您要将密钥 k3 重命名为 k4:

temp_dict = {'k1':'v1', 'k2':'v2', 'k3':'v3'}
temp_dict['k4']= temp_dict.pop('k3')