使用python中的引用dict更新第二级dict数组对象

时间:2018-06-02 10:08:50

标签: python python-3.x

我有一系列的dicts,如果有另一个dicts数组,每个都在其中。我这样的原始词典

[{'substepheading': 'Heading 1',
  'substepnumber': '1',
  'substepparams': [{'name': 'upload file', 'paramselected': 'no'}]},
 {'substepheading': 'Heading 2',
  'substepnumber': '2',
  'substepparams': [{'name': 'clean data', 'paramselected': 'no'}]}]

我有另一个dict,其中包含指定步骤编号的更新和这样的参数

[{'substepnumber': 2, 'substepparams': [{'name': 'clean room'}]}]

我尝试了这个但是子阵列没有正确更新

    for substep in substepdetails:
        for modifiedsubstep in substepdetailstoupdate:
            if((modifiedsubstep['substepnumber']) == int(substep['substepnumber'])):
                substep.update(modifiedsubstep)

第二级dicts数组正在被覆盖,如此

[{'substepheading': 'choose file',
  'substepnumber': '1',
  'substepparams': [{'name': 'upload file', 'paramselected': 'no'}]},
 {'substepheading': 'prepare the data',
  'substepnumber': '2',
  'substepparams': [{'name': 'clean room'}]}]

我知道我可以为这个特殊情况添加一个内部循环,但我想知道在这样的情况下是否有更优雅的方法更新dicts,特别是如果可以有多个这样的子级别

编辑:所需的输出就像这样

[{'substepheading': 'choose file',
      'substepnumber': '1',
      'substepparams': [{'name': 'upload file', 'paramselected': 'no'}]},
     {'substepheading': 'prepare the data',
      'substepnumber': '2',
      'substepparams': [{'name': 'clean room', 'paramselected': 'no'}]}]

1 个答案:

答案 0 :(得分:1)

您真正需要的只是数据上的两个循环和一个更新循环(没有嵌套循环)。我们的想法是创建一个dictrecords,将substepnumber映射到substepparams。 (请注意,这假设不重复substepparams。这种情况可以通过一些额外的工作来处理。)

对于每次更新,您都可以在分摊的O(1)时间内访问相应的substepnumber并更新相关substepparams列表中的每个dict。

由于recordsdata引用相同的词组,原始数据将自动更新。

data = [
    {
        "substepheading": "Heading 1",
        "substepnumber": "1",
        "substepparams": [{"name": "upload file", "paramselected": "no"}],
    },
    {
        "substepheading": "Heading 2",
        "substepnumber": "2",
        "substepparams": [{"name": "clean data", "paramselected": "no"}],
    },
]

# converted substepnumber to str in order to match the data format.
updates = [{"substepnumber": "2", "substepparams": [{"name": "clean room"}]}]

records = {d["substepnumber"]: d["substepparams"] for d in data}
for num, params in ((d["substepnumber"], d["substepparams"]) for d in updates):
    [dct.update(upd) for dct in records[num] for upd in params]


[
    {
        "substepheading": "Heading 1",
        "substepnumber": "1",
        "substepparams": [{"name": "upload file", "paramselected": "no"}],
    },
    {
        "substepheading": "Heading 2",
        "substepnumber": "2",
        "substepparams": [{"name": "clean room", "paramselected": "no"}],
    },
]