Home > Enterprise >  Change keys in a dictionary
Change keys in a dictionary

Time:07-13

I have this dictionary.

maximo = {'CodChamado': 50, '_14984|Top Down:': 0, '_14985|Hierarquia solicitante:': 0}

And I want to change these keys "_14984|Top Down:" and "_14985|Hierarquia solicitante:" to

new_key = ['Campo Extra|Top Down:', 'Campo Extra|Hierarquia solicitante:']

The result of that is the new dictionary:

new_maximo = {'CodChamado': 50, 'Campo Extra|Top Down:': 0, 'Campo Extra|Hierarquia solicitante:': 0}

I tried to do this but it doesn't work:

old_key = []
for key in self.maximo:
    if key[0] == "_":
        old_key.append(key)

for i in new_key:
    for j in old_key:
        self.maximo[i] = self.maximo[j]
        del self.maximo[j]

This error appears:

File "<string>", line 3, in <module>
KeyError: '_14984|Top Down:'

Anyone knows how to do it? I need it to be done kind of dynamic because this is not the only dictionary I'm using, but all of the keys I need to change have this pattern with "_" in key[0].

CodePudding user response:

You don't need two loops to do this. If you know the original key, then to get the new key all you need to do is replace the part beginning at "_" and ending at "|" with "Campo Extra|". You can do this using a regular expression like so:

import re

new_dict = {
    re.sub(r"^_.*?\|", "Campo Extra|", k): v
    for k, v in maximo.items()
}

Instead of replacing the keys in the original dict, this creates a new dictionary that looks like this:

{'CodChamado': 50,
 'Campo Extra|Top Down:': 0,
 'Campo Extra|Hierarquia solicitante:': 0}

An explanation of the regex (Try it online):

^_.*?\|
^        : Start of the string
 _       : An underscore
  .*?    : Zero or more of any character, lazy match
     \|  : A pipe character

If you want to replace the keys in the original dictionary, then you can do it like so:

for k in list(maximo):
    new_key = re.sub(r"^_.*?\|", "Campo Extra|", k)
    if new_key != k:
        maximo[new_key] = maximo.pop(k)

If you want to avoid regex altogether, then simply replace the call to re.sub with a function that does the same thing:

def modify_key(k, replacement):
    if k[0] != "_": return k
    try:
        pipe_loc = k.index("|")
        new_k = "Campo Extra"   k[pipe_loc:]
        return new_k
    except ValueError:
        # "|" not found in k
        return k

new_dict = {
    modify_key(k, "Campo Extra"): v
    for k, v in maximo.items()
}

CodePudding user response:

ho about changing the dict to json string and then replace _14984 and save back to dictionary:

import json
import re


maximo = {'CodChamado': 50, '_14984|Top Down:': 0, '_14985|Hierarquia solicitante:': 0}
string = json.dumps(maximo)
string
>'{"CodChamado": 50, "_14984|Top Down:": 0, "_14985|Hierarquia solicitante:": 0}'

correct_str = re.sub('_[0-9]{5}', 'Campo Extra', string)
correct_str
>'{"CodChamado": 50, "Campo Extra|Top Down:": 0, "Campo Extra|Hierarquia solicitante:": 0}'

correct_dict = json.loads(correct_str)
correct_dict
>{'CodChamado': 50,
 'Campo Extra|Top Down:': 0,
 'Campo Extra|Hierarquia solicitante:': 0}

CodePudding user response:

The minimum modification of your original code: Change the last snippet into

for i, j in zip(new_key, old_key):
    maximo[i] = maximo[j]
    del maximo[j]

Alternatively, you could refer to other answers for better refactoring (using re, etc.).

CodePudding user response:

If I may help you out in your predicament. You can loop through the keys in your python dictionary using the keys() method so the first step would be looping through the keys in your dictionary then using if statements to replace the key and removing the old key using the del key word:

for key in maximo.keys():
    if key == "_14984|Top Down:"
       maximo['Campo Extra|Top Down'] = maximo["_14984|Top Down:"]
       del maximo["_14984|Top Down:"]
    if key ==  "_14985|Hierarquia solicitante:":
       maximo["Campo Extra|Hierarquia solicitante:"] = maximo["_14985|Hierarquia solicitante:"]
       del maximo["_14985|Hierarquia solicitante:"]
  • Related