Как я могу создать новый вложенный словарь из старого вложенного словаря с обновленными ключами и значением?

#python #python-3.x #dictionary #nested

Вопрос:

В настоящее время я пытаюсь создать новый словарь из непригодного словаря, но у меня возникают трудности с обновлением/созданием новых ключей на основе количества кортежей в «Приемлемом» ключе.

 dirty_dictionary = {'DOG': {'Acceptable': ([[35, 38]], 'DOG_GROUP'),
                    'Unacceptable': ([[2], [29], [44], [50], [54], [60]], 'DOG_GROUP')},
                    'CAT': {'Acceptable': ([[3, 6], [100, 101]], 'CAT_GROUP'), 'Unacceptable': ([[12], [18], [45], [51], [61]], 'CAT_GROUP')},
                    'FISH': {'Acceptable': ([], 'FISH_GROUP'), 'Unacceptable': ([[13], [19], [22], [28], [34]], 'FISH_GROUP')},
                    'COW': {'Acceptable': ([[87, 69]], 'COW_GROUP'), 'Unacceptable': ([], 'COW_GROUP')}}

new_dict = {}
for key, values in dirty_dictionary.items():
    if len(values['Acceptable'][0]) == 0:
        new_dict[dirty_dictionary[key]['Acceptable'][-1]] = {'Acceptable': []}
    for oids in values['Acceptable'][0]:
        if len(values['Acceptable'][0]) == 1:
            new_dict[dirty_dictionary[key]['Acceptable'][-1]] = {'Acceptable': oids}
        if len(values['Acceptable'][0]) > 1:
            for i in range(len(values['Acceptable'][0])):
                new_dict[dirty_dictionary[key]['Acceptable'][-1]   F'_{i}'] = {'Acceptable': values['Acceptable'][0][i]}

    # for oids in values['Unacceptable'][0]:
    #     if len(values['Unacceptable'][0]) == 1:
    #         new_dict[dirty_dictionary[key]['Unacceptable'][-1]].update({'Unacceptable': oids})
    #     if len(values['Unacceptable'][0]) > 1:
    #         for i in range(len(values['Unacceptable'][0])):
    #             new_dict[dirty_dictionary[key]['Unacceptable'][-1]   F'_{i}'].update({'Unacceptable': values['Unacceptable'][0][i]})

print(new_dict)
 

Я могу создать новый словарь со всеми «Приемлемыми» ключами/значениями, но я застрял на обновлении словаря с «Неприемлемым», поскольку необходимо создать новые группы, если len значений [«Приемлемо»] [0] > 1.

Цель состоит в том, чтобы окончательный словарь выглядел так:

 final = {'DOG_GROUP': {'Acceptable': [35, 38], 'Unacceptable': [2, 29, 44, 50, 54, 60]},
         'CAT_GROUP_0': {'Acceptable': [3, 6], 'Unacceptable': []},
         'CAT_GROUP_1': {'Acceptable': [100, 101], 'Unacceptable': [12, 18, 45, 51, 61]},
         'FISH_GROUP': {'Acceptable': [], 'Unacceptable': [13, 19, 22, 28, 34]},
         'COW_GROUP': {'Acceptable': [87, 69], 'Unacceptable': []}}
 

Комментарии:

1. Можете ли вы объяснить, почему CAT_GROUP_0 имеет 'Unacceptable': [] и CAT_GROUP_1 имеет 'Unacceptable': [12, 18, 45, 51, 61] в конечном итоге

2. @MazedulIslam К сожалению, программа, которая будет использовать этот словарь, нуждается в таком формате. В конце концов, «Неприемлемые» значения должны быть в 1 списке под CAT_GROUP, а другой должен быть пустым списком, чтобы программа могла правильно его прочитать

3. Итак, если Acceptable имеет длину 3 для группы CAT, то первые 2 группы CAT будут иметь Unacceptable пустой массив, а последняя будет иметь все Unacceptable значения в одном массиве. Правильно ли я понимаю?

4. @MazedulIslam, Ты прав!

Ответ №1:

Попробуй вот это.

 dirty_dictionary = {'DOG': {'Acceptable': ([[35, 38]], 'DOG_GROUP'), 'Unacceptable': ([[2], [29], [44], [50], [54], [60]], 'DOG_GROUP')}, 'CAT': {'Acceptable': ([[3, 6], [100, 101]], 'CAT_GROUP'), 'Unacceptable': ([[12], [18], [45], [51], [61]], 'CAT_GROUP')}, 'FISH': {'Acceptable': ([], 'FISH_GROUP'), 'Unacceptable': ([[13], [19], [22], [28], [34]], 'FISH_GROUP')}}

new_dict = {}

# assign text strings in variable to get suggestion in IDE
acceptable = 'Acceptable'
unacceptable = 'Unacceptable'

for key, values in dirty_dictionary.items():
    group = values[acceptable][1]
    if len(values[acceptable][0]) <= 1:
        new_dict[group] = {}
        new_dict[group][acceptable] = [y for x in values[acceptable][0] for y in x]
        new_dict[group][unacceptable] = [y for x in values[unacceptable][0] for y in x]
    else:
        for idx, item in enumerate(values[acceptable][0]):
            group_temp = group   '_'   str(idx 1)
            new_dict[group_temp] = {}
            new_dict[group_temp][acceptable] = item
            # if last item then give all unacceptable as a single array
            if idx == len(values[acceptable][0]) - 1:
                new_dict[group_temp][unacceptable] = [y for x in values[unacceptable][0] for y in x]
            else: # else empty array
                new_dict[group_temp][unacceptable] = []

print(new_dict)
 

Ответ №2:

Это должно работать так, как описано:

 dirty_dictionary = {'DOG': {'Acceptable': ([[35, 38]], 'DOG_GROUP'),
                    'Unacceptable': ([[2], [29], [44], [50], [54], [60]], 'DOG_GROUP')},
                    'CAT': {'Acceptable': ([[3, 6], [100, 101]], 'CAT_GROUP'), 'Unacceptable': ([[12], [18], [45], [51], [61]], 'CAT_GROUP')},
                    'FISH': {'Acceptable': ([], 'FISH_GROUP'), 'Unacceptable': ([[13], [19], [22], [28], [34]], 'FISH_GROUP')}}

new_dict = {}
for _, next_group in dirty_dictionary.items():
    next_group_name = next_group['Acceptable'][1]
    if len(next_group['Acceptable'][0]) > 1: # Split the Acceptables across several keys
        for i, next_acceptable in enumerate(next_group['Acceptable'][0]):
            new_dict[f"{next_group_name}_{i}"] = {'Acceptable': next_acceptable, 'Unacceptable': []}
        new_dict[f'{next_group_name}_{i}']['Unacceptable'] = [next_entry for unacceptable in next_group['Unacceptable'][0] for next_entry in unacceptable]
    else: # Nothing else to consider
        new_dict[f'{next_group_name}'] = {
            'Acceptable': [next_entry for acceptable in next_group['Acceptable'][0] for next_entry in acceptable],
            'Unacceptable': [next_entry for unacceptable in next_group['Unacceptable'][0] for next_entry in unacceptable]
        }

for k, v in new_dict.items():
    print(f'{k}: {v}')
 

Возвращает следующий результат:

 DOG_GROUP: {'Acceptable': [35, 38], 'Unacceptable': [2, 29, 44, 50, 54, 60]}
CAT_GROUP_0: {'Acceptable': [3, 6], 'Unacceptable': []}
CAT_GROUP_1: {'Acceptable': [100, 101], 'Unacceptable': [12, 18, 45, 51, 61]}
FISH_GROUP: {'Acceptable': [], 'Unacceptable': [13, 19, 22, 28, 34]}
 

Ответ №3:

Данные испытаний:

 dirty_dictionary = {
    "DOG": {
        "Acceptable": ([[35, 38]], "DOG_GROUP"),
        "Unacceptable": ([[2], [29], [44], [50], [54], [60]], "DOG_GROUP"),
    },
    "CAT": {
        "Acceptable": ([[3, 6], [100, 101]], "CAT_GROUP"),
        "Unacceptable": ([[12], [18], [45], [51], [61]], "CAT_GROUP"),
    },
    "FISH": {
        "Acceptable": ([], "FISH_GROUP"),
        "Unacceptable": ([[13], [19], [22], [28], [34]], "FISH_GROUP"),
    },
    "COW": {"Acceptable": ([[87, 69]], "COW_GROUP"), "Unacceptable": ([], "COW_GROUP")},
}
 

Решение:

 import itertools
flatten = itertools.chain.from_iterable

new_dict = {}
for key, value in dirty_dictionary.items():
    accept_status = {"Acceptable": [], "Unacceptable": []}
    if value["Acceptable"][0]:
        accept_status["Acceptable"] = list(flatten(value["Acceptable"][0]))
    if value["Unacceptable"][0]:
        accept_status["Unacceptable"] = list(flatten(value["Unacceptable"][0]))
    new_dict[key] = accept_status
 

Выход:

 {'DOG': {'Acceptable': [35, 38], 'Unacceptable': [2, 29, 44, 50, 54, 60]},
 'CAT': {'Acceptable': [3, 6, 100, 101], 'Unacceptable': [12, 18, 45, 51, 61]},
 'FISH': {'Acceptable': [], 'Unacceptable': [13, 19, 22, 28, 34]},
 'COW': {'Acceptable': [87, 69], 'Unacceptable': []}}
 

Ответ №4:

поскольку вы создаете ключи из приемлемого, попробуйте этот код :

 new_dict = {}
for key, values in dirty_dictionary.items():
    if len(values['Acceptable'][0]) == 0:
        new_dict[dirty_dictionary[key]['Acceptable'][-1]] = {'Acceptable': []}
for oids in values['Acceptable'][0]:
    if len(values['Acceptable'][0]) == 1:
        new_dict[dirty_dictionary[key]['Acceptable'][-1]] = {'Acceptable': oids}
    if len(values['Acceptable'][0]) > 1:
        for i in range(len(values['Acceptable'][0])):
            new_dict[dirty_dictionary[key]['Acceptable'][-1]   F'_{i}'] = {'Acceptable': values['Acceptable'][0][i]}

for oids in values['Unacceptable'][0]:
    if len(values['Unacceptable'][0]) == 1:
        new_dict[dirty_dictionary[key]['Unacceptable'][-1]].update({'Unacceptable': oids})
    if len(values['Unacceptable'][0]) > 1:
        Unacceptable = []
        for i in range(len(values['Unacceptable'][0])):
            for j in range(len(values['Unacceptable'][0][i])):
                Unacceptable.append(values['Unacceptable'][0][i][j])

        if len(values['Acceptable'][0]) > 1:
            for k in range(len(values['Acceptable'][0])):
                new_dict[dirty_dictionary[key]['Acceptable'][-1]   F'_{k}'].update({'Unacceptable': Unacceptable})
        else:
            new_dict[dirty_dictionary[key]['Unacceptable'][-1]].update({'Unacceptable': Unacceptable})

print(new_dict)
 

и выход есть :

 {'DOG_GROUP': {'Acceptable': [35, 38], 'Unacceptable': [2, 29, 44, 50, 54, 60]}, 
'CAT_GROUP_0': {'Acceptable': [3, 6], 'Unacceptable': [12, 18, 45, 51, 61]}, 
'CAT_GROUP_1': {'Acceptable': [100, 101], 'Unacceptable': [12, 18, 45, 51, 61]}, 
'FISH_GROUP': {'Acceptable': [], 'Unacceptable': [13, 19, 22, 28, 34]}}