字典和嵌套字典之间的Python键匹配,并将新值写入嵌套字典

2024-09-30 18:23:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个字典,一个是标准的键/值对字典,另一个是嵌套的OrderedDict,具有标准字典的公共键名,但有空值

我正在寻找一种从标准键/值字典(properties\u dict)中提取值的方法,并将这些值放入键匹配的嵌套字典(blank\u dict)中

我曾研究过使用“isinstance”来迭代其他列表/字典中的值,但现在我开始怀疑我是否走错了路,可能会使它过于复杂。我遇到的另一个问题是,一个值“Variant”是列表形式的,因此我们正在寻找一种方法,在遍历OrderedDict时将每个值从列表中弹出

我在下面添加了我的尝试

from collections import OrderedDict


def walkdicts(blankdict, propsdict):
    for k, v in blankdict.items():
        for k2, v2 in propsdict.items():
            if k == k2:
                blankdict[k] = v2
        if isinstance(v, dict):
            walkdicts(v, propsdict)
        elif isinstance(v, list):
            for i in v:
                walkdicts(i[0], propsdict)

    return blankdict


properties_dict = {'A_ID': '2702',
 'Sys': 'MySystem',
 'Namespace': 'SomeNamespace',
 'Vers': '112A',
 'Variant': ['1','2'],
 'SpecID': 'Target1',
 'Seq': '12345',
 'Match': 'ABCDEFG',
 'Time': '200',
 'Case1': 'A',
 'Type': 'Include',
 'MyRef': '1010',
 'Case2': 'B'}


blank_dict =   OrderedDict([('Main', OrderedDict([
                    ('Vers', ''), 
                    ('Namespace', ''), 
                    ('Sys', ''), 
                    ('A_ID', ''),
                    ('Variant', '1'),
                ('Sec1', OrderedDict([
                    ('RequestID', OrderedDict([
                        ('Case1', ''), 
                        ('Case2', '')])), 
                    ('Variant', ''), 
                    ('MyRef', '')])), 
                ('Sec2', OrderedDict([
                    ('UHD', OrderedDict([
                        ('SpecID', ''), 
                        ('Type', ''), 
                        ('AD2W', OrderedDict([
                            ('Time', ''), 
                            ('Match', ''), 
                            ('Seq', '')]))]))]))]))])


new_dict = walkdicts(blank_dict, properties_dict)

print(new_dict)

下面是我要查找的输出顺序字典:

    new_dict =   OrderedDict([('Main', OrderedDict([
                    ('Vers', '112A'), 
                    ('Namespace', 'SomeNamespace'), 
                    ('Sys', 'MySystem'), 
                    ('A_ID', '2702'),
                    ('Variant', '1'),
                ('Sec1', OrderedDict([
                    ('RequestID', OrderedDict([
                        ('Case1', 'A'), 
                        ('Case2', 'B')])), 
                    ('Variant', '2'), 
                    ('MyRef', '1010')])), 
                ('Sec2', OrderedDict([
                    ('UHD', OrderedDict([
                        ('SpecID', 'Target1'), 
                        ('Type', 'Include'), 
                        ('AD2W', OrderedDict([
                            ('Time', '200'), 
                            ('Match', 'ABCDEFG'), 
                            ('Seq', '12345')]))]))]))]))])

谢谢你抽出时间


Tags: inid列表for标准字典propertiesdict
1条回答
网友
1楼 · 发布于 2024-09-30 18:23:14

下面是一个函数,它返回一个嵌套的OrderedDict,该嵌套的template中的结构与props中执行查找填充的值相匹配:

def populate(template, props, prop_indexes=None):
    if prop_indexes is None:
        prop_indexes = {}
    result = OrderedDict()
    for k, v in template.items():
        if isinstance(v, dict):
            result[k] = populate(v, props, prop_indexes)
            continue
        if k in props.keys():
            if isinstance(props[k], list):
                if k not in prop_indexes:
                    prop_indexes[k] = 0
                index = prop_indexes[k] % len(props[k])
                result[k] = props[k][index]
                prop_indexes[k] += 1
            else:
                result[k] = props[k]
    return result

请注意:

  • prop_indexes用于跟踪定义为值列表的每个属性的位置。使用模(%)运算符,如果target中的实例多于列表中的值,我们可以在列表中重复循环
  • 因为props是一个字典,所以不需要循环遍历它。相反,只需检查密钥是否存在
  • 这仍然需要一些工作来优雅地处理边缘情况和错误条件,但我只想演示一种工作方法。一个主要的假设是template只由嵌套字典组成

使用示例代码中的blank_dict(通过添加额外的Variant键稍微修改,请参见输出后的注释)和properties_dict的定义,下面是一小段代码:

import pprint
pp = pprint.PrettyPrinter()

print("## blank_dict ##")
pp.pprint(blank_dict)

new_dict = populate_new(blank_dict, properties_dict)

print("## new_dict ##")
pp.pprint(new_dict)

这里是输出(pprint并没有真正呈现出OrderedDict所有的美丽,但它完成了任务):

## blank_dict ##
OrderedDict([('Main',
              OrderedDict([('Vers', ''),
                           ('Namespace', ''),
                           ('Sys', ''),
                           ('A_ID', ''),
                           ('Variant', ''),
                           ('Sec1',
                            OrderedDict([('RequestID',
                                          OrderedDict([('Case1', ''),
                                                       ('Case2', '')])),
                                         ('Variant', ''),
                                         ('MyRef', '')])),
                           ('Sec2',
                            OrderedDict([('UHD',
                                          OrderedDict([('SpecID', ''),
                                                       ('Type', ''),
                                                       ('Variant', ''),
                                                       ('AD2W',
                                                        OrderedDict([('Time',
                                                                      ''),
                                                                     ('Match',
                                                                      ''),
                                                                     ('Seq',
                                                                      '')]))]))]))]))])
## new_dict ##
OrderedDict([('Main',
              OrderedDict([('Vers', '112A'),
                           ('Namespace', 'SomeNamespace'),
                           ('Sys', 'MySystem'),
                           ('A_ID', '2702'),
                           ('Variant', '1'),
                           ('Sec1',
                            OrderedDict([('RequestID',
                                          OrderedDict([('Case1', 'A'),
                                                       ('Case2', 'B')])),
                                         ('Variant', '2'),
                                         ('MyRef', '1010')])),
                           ('Sec2',
                            OrderedDict([('UHD',
                                          OrderedDict([('SpecID', 'Target1'),
                                                       ('Type', 'Include'),
                                                       ('Variant', '1'),
                                                       ('AD2W',
                                                        OrderedDict([('Time',
                                                                      '200'),
                                                                     ('Match',
                                                                      'ABCDEFG'),
                                                                     ('Seq',
                                                                      '12345')]))]))]))]))])

注意:我添加了一个额外的Variant实例来演示如何填充3个实例,即使在properties_dict中只指定了2个值

相关问题 更多 >