我有两个字典,一个是标准的键/值对字典,另一个是嵌套的 OrderedDict,具有标准字典的公共键名,但有空值。
我正在寻找一种方法来从标准键/值字典 (properties_dict) 中提取值并将这些值放入我的键匹配的嵌套字典 (blank_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)
这是我正在寻找的输出 Ordered 字典:
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')]))]))]))]))])
感谢您的时间。
答案 0 :(得分:1)
这是一个函数,它返回一个嵌套的 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 个值