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]
How to change the name of a key in a dictionary, ideally without deleting it?
performance - Efficient renaming of dict keys from another dict's values - Python - Code Review Stack Exchange
How can I rename multiple files according to a dictionary? (possibly using os.rename)
Rename dictionary keys/values in python - Stack Overflow
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?
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()
}
So I've created a dictionary with key: "current_filename" and value:"new_filename"
I want to create a function that automatically renames 10,000 of files according to the dictionary.
I'm having an issue setting up a proper 'for loops'.
Below is what I have so far.
def get_values():
for count, filename in enumerate(os.listdir(path_)):
# get new name that matches old name
key_file = os.listdir(path_)[count]
for key, value in dict_.items():
if key_file == key:
os.rename(key_file,value)
continueYour help is greatly appreciated!