Замена указанного ключа c во вложенном словаре без влияния на другие ключи - PullRequest
0 голосов
/ 12 февраля 2020

Работая над определенной функцией поиска и замены неправильного ключа для образца словаря musi c, я не могу найти правильный код для этого.

my_dict = {
    1: {
        "Artist": "Pat Metheny",
        "Album": {"Offramp": {"Year": "1982"},
                  "First Cicrle": {"Year": "1985"}}
    },
    2: {
        "Artist": "William Ackerman",
        "Album": {"Imaginary Roads": {"Year": "1986"},
                  "Passage": {"Year": "1979"}}
    },
    3: {
        "Artist": "John Coltrane",
        "Album": {"A Love Supreme": {"Year": "1960"},
                  "Ballads": {"Year": "1966"}}
    }
}

add2dict = {}

def fix_case(x):
    x = ("".join([a if a.isupper() else b for a, b in zip(x, x.title())]))
    return x


def repl(rep):
    index = int(rep[0])
    for d, g in my_dict[int(rep[0])].items():
        if rep[1] in g:
            print('found it')
            print(my_dict[int(rep[0])]['Artist'])
            my_dict[int(rep[0])]['Artist'] = rep[2]
            print(my_dict)
        elif rep[1] in my_dict[index]['Album'].keys(): #check 'Album' keys for rep[1]
            print('found it in ', my_dict[index]['Album'])

            for alb, year in my_dict[index]['Album'].items():
                if alb == rep[1]:
                    my_dict[index]['Album'] = rep[1][year]

            print(my_dict)

        elif rep[1] in my_dict[index]['Year']:
            print('found it')
            my_dict[int(rep[0])]['Year'] = rep[2]

            print(my_dict[1])

        return


ndx2 = 1

keys = []
while True:

    def printData():
        for d, g in my_dict.items():
            print(f'ID: {d}')
            print('Artist:', g['Artist'])
            print("Albums:")
            for album, metadata in g['Album'].items():
                year = metadata['Year']
                print(f'-{album} ({year})')
            print()


    ndx2 = 1
    choice = int(input("1:Add an entry:\n2:Replace an entry\n3:quit or <ENTER>\n:"))
    if choice == int(1):
        Add_dbase = input('Add an entry: ')
    elif choice == int(2):
        printData()
        dbase_repl = input('Enter ID followed by \'/\' and \'old word\'/\'replace word\'')
        repl_keys = dbase_repl.split("/")
        print(my_dict[int(repl_keys[0])].items())
        repl(repl_keys)
        printData()
        break
    elif choice == int(3) or "":
        print("Nothing entered. Bye.")
        break
    else:
        break

В моей функции def repl (rep) , обрабатывает ситуацию для изменения ключа альбома. Я передаю индекс Artist, ключ с ошибкой и правильный ключ как 'rep [0]', rep [1], rep [2] соответственно. В первом блоке elif я могу сузить правильный ключ, но не могу найти правильный код, чтобы изменить его, не затрагивая другой ключ альбома. Например, альбом «Первый Цикл» написан неправильно, и я хочу изменить его на «Первый круг». Я пытался использовать .replace, .update, .pop и многие комбинации, но я не получаю только то, что изменилось имя ключа. Есть идеи, пожалуйста? Спасибо!

1 Ответ

0 голосов
/ 12 февраля 2020

Вам нужно проверить каждый ключ и значение словаря, чтобы найти конкретную c фразу. Затем обновите данные словаря на основе измененных значений ключа. replace список содержит: [artist_id, old_key, new_key]

data = {
    1: {
        "Artist": "Pat Metheny",
        "Album": {"Offramp": {"Year": "1982"},
                  "First Cicrle": {"Year": "1985"}}
    },
    2: {
        "Artist": "William Ackerman",
        "Album": {"Imaginary Roads": {"Year": "1986"},
                  "Passage": {"Year": "1979"}}
    },
    3: {
        "Artist": "John Coltrane",
        "Album": {"A Love Supreme": {"Year": "1960"},
                  "Ballads": {"Year": "1966"}}
    }
}


replace = [1, 'First Cicrle', 'First Circle']

for k, v in data.items():
    if k == replace[0]:
        out = {}
        for key, value in data.get(replace[0]).items():
            if key == replace[1]:
                out[replace[2]] = value
            else:
                if isinstance(value, dict):
                    value3 = {}
                    for key2, value2 in value.items():
                        if key2 == replace[1]:
                            value3[replace[2]] = value2
                        else:
                            value3[key2] = value2
                    out[key] = value3
                else:
                    out[key] = value
        data[k] = out

Вывод:

{1: {'Artist': 'Pat Metheny', 'Album': {'Offramp': {'Year': '1982'}, 'First Circle': {'Year': '1985'}}}, 2: {'Artist': 'William Ackerman', 'Album': {'Imaginary Roads': {'Year': '1986'}, 'Passage': {'Year': '1979'}}}, 3: {'Artist': 'John Coltrane', 'Album': {'A Love Supreme': {'Year': '1960'}, 'Ballads': {'Year': '1966'}}}}
...