For a regular dict, you can use:
mydict[k_new] = mydict.pop(k_old)
This will move the item to the end of the dict, unless k_new was already existing in which case it will overwrite the value in-place.
For a Python 3.7+ dict where you additionally want to preserve the ordering, the simplest is to rebuild an entirely new instance. For example, renaming key 2 to '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}
The same is true for an OrderedDict, where you can't use dict comprehension syntax, but you can use a generator expression:
OrderedDict((k_new if k == k_old else k, v) for k, v in od.items())
Modifying the key itself, as the question asks for, is impractical because keys are hashable which usually implies they're immutable and can't be modified.
Answer from wim on Stack OverflowFor a regular dict, you can use:
mydict[k_new] = mydict.pop(k_old)
This will move the item to the end of the dict, unless k_new was already existing in which case it will overwrite the value in-place.
For a Python 3.7+ dict where you additionally want to preserve the ordering, the simplest is to rebuild an entirely new instance. For example, renaming key 2 to '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}
The same is true for an OrderedDict, where you can't use dict comprehension syntax, but you can use a generator expression:
OrderedDict((k_new if k == k_old else k, v) for k, v in od.items())
Modifying the key itself, as the question asks for, is impractical because keys are hashable which usually implies they're immutable and can't be modified.
Using a check for newkey!=oldkey, this way you can do:
if newkey!=oldkey:
dictionary[newkey] = dictionary[oldkey]
del dictionary[oldkey]
python - Change the name of a key in dictionary - Stack Overflow
performance - Efficient renaming of dict keys from another dict's values - Python - Code Review Stack Exchange
Why doesn't rename seem to work for me with these invalid key names in my dictionary?
Update key, Rename Key C# Dictionary
Videos
I have { key1 : value1 }, which I want to rename to { key2 : value1 }. Google has told me to just delete key1 and create a new key2, but value1 is a complicated, frequently-changing mess, and I don't really want to have to keep updating it.
Any ideas? Is there a method that I'm missing?
Easily done in 2 steps:
dictionary[new_key] = dictionary[old_key]
del dictionary[old_key]
Or in 1 step:
dictionary[new_key] = dictionary.pop(old_key)
which will raise KeyError if dictionary[old_key] is undefined. Note that this will delete dictionary[old_key].
>>> dictionary = { 1: 'one', 2:'two', 3:'three' }
>>> dictionary['ONE'] = dictionary.pop(1)
>>> dictionary
{2: 'two', 3: 'three', 'ONE': 'one'}
>>> dictionary['ONE'] = dictionary.pop(1)
Traceback (most recent call last):
File "<input>", line 1, in <module>
KeyError: 1
if you want to change all the keys:
d = {'x':1, 'y':2, 'z':3}
d1 = {'x':'a', 'y':'b', 'z':'c'}
In [10]: dict((d1[key], value) for (key, value) in d.items())
Out[10]: {'a': 1, 'b': 2, 'c': 3}
if you want to change single key: You can go with any of the above suggestion.
I'd use a dict comprehension:
pretty_dict = {replacement_keys[k]: v for k, v in ugly_dict.items()}
This throws an error if replacement_keys (keyMapping) is missing any k. You might want to handle that with a default that falls back to the original key:
pretty_dict = {replacement_keys.get(k, k): v for k, v in ugly_dict.items()}
Time complexity is linear, assuming constant time dict lookups.
The main point of dicts is fast lookups, not iteration, so alarm bells should sound if you find yourself doing nested loops over multiple dicts.
Style suggestions:
- Use
snake_caserather thancamelCaseper PEP-8. - Generally avoid appending the type to every variable,
users_count,source_string,names_list,translation_dictand so forth, although I assume this is for illustrative purposes here. .keys()is superfluous as far as I know, but then again it doesn't hurt. You shouldn't need to loop over keys on a dict often.
The point of dictionaries is that lookup is fast, but you are not using that even though your keyMapping already is a dictionary. Let us look at your code.
prettyDict = {}
for mkey, mval in keyMapping.items():
for ukey in uglyDict.keys():
if mkey == ukey:
prettyDict[mval] = uglyDict[mkey]
Even if uglyDict is small, you iterate over all element of the key mapping. This seems to be a bad starting point, so let us reverse the two loops.
prettyDict = {}
for ukey in uglyDict.keys():
for mkey, mval in keyMapping.items():
if mkey == ukey:
prettyDict[mval] = uglyDict[mkey]
In the last line, mkey equals ukey, so we can change that to uglyDict[ukey], and of course you know how to avoid that lookup altogether:
prettyDict = {}
for ukey, uval in uglyDict.items():
for mkey, mval in keyMapping.items():
if mkey == ukey:
prettyDict[mval] = uval
Let us now concentrate on the middle part:
for mkey, mval in keyMapping.items():
if mkey == ukey:
Here we look for the value of ukey in keyMapping, but surely that is what dictionaries are for and we don't have to iterate over all items to do so.
prettyDict = {}
for ukey, uval in uglyDict.items():
if ukey in keyMapping:
mval = keyMapping[ukey]
prettyDict[mval] = uval
This is much better. From here, we can reformulate this using a dictionary comprehension like in ggorien's answer, if you prefer that.
prettyDict = {
keyMapping[ukey]: uval
for ukey, uval in uglyDict.items()
if ukey in keyMapping
}
More importantly, you should decide how to handle the case that ukey is not in keyMapping. (Your example seems to have that got wrong with ORDER_NUMBER, btw.) If this would be a error, just omit the if ukey in keyMapping and handle the exception elsewhere. Or maybe you would like to keep the original key in that case:
prettyDict = {
keyMapping.get(ukey, ukey): uval
for ukey, uval in uglyDict.items()
}