如何使用更新的键和值从旧的嵌套字典创建新的嵌套字典?

时间:2021-07-25 16:49:33

标签: 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 值 ['Acceptable'][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': []}}

4 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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 = {}
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]}

答案 2 :(得分:0)

测试数据:

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': []}}

答案 3 :(得分:0)

因为您从 Acceptable 创建密钥 试试这个代码:

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]}}