追加词典列表,在一个词典中附加键,并以嵌套字典作为其值

时间:2019-07-10 13:33:22

标签: python list dictionary list-comprehension

我有一个模式,并且有一个嵌套字段列表,应该在其中。 基本上,我拥有的是:

[{'name': 'a', 'type': 'string'}, 
{'name': 'b', 'type': 'string'}, 
{'name': 'c', 'type': 'string'}, 
{'name': 'd', 'type': 'string'}, 
{'name': 'e', 'type': 'string'}, 
{'name': 'attr', 'type': 'string'}, 
{'name': 'f', 'type': 'string'},
{'name': 'g', 'type': 'string'}, 
{'name': 'h', 'type': 'string'}, 
{'name': 'i', 'type': 'string'}, 
{'name': 'j', 'type': 'string'}, 
{'name': 'k', 'type': 'string'}]

但是,当“名称”为“ attr”时,我想向其添加另一个字典k-v对,其键为“ fields”,值作为另一个嵌套的字典列表,格式与上述相同。这将使其看起来像:

[{'name': 'a', 'type': 'string'}, 
{'name': 'b', 'type': 'string'}, 
{'name': 'c', 'type': 'string'}, 
{'name': 'd', 'type': 'string'}, 
{'name': 'e', 'type': 'string'}, 
{'name': 'attr', 'type': 'string', 'fields': [{'name': 'aa',....}], 
{'name': 'f', 'type': 'string'},
{'name': 'g', 'type': 'string'}, 
{'name': 'h', 'type': 'string'}, 
{'name': 'i', 'type': 'string'}, 
{'name': 'j', 'type': 'string'}, 
{'name': 'k', 'type': 'string'}]

下面,master_schema_set和nestedschemaset都是我转换的集合。

finalschema = [{'name':l} for l in master_schema_set]
finalschemanested = [{'name':l} for l in nestedschemaset]

for i in finalschema:
    i.update({"type":'string'}) #all types will always be string
    for item,val in i.items():
        if val == 'attr':
            i.update({'fields':finalschemanested})

运行此命令会给我一个错误“在迭代过程中词典更改了大小”,但最终这就是我想要的。有什么更好的方法来实现这一目标?

3 个答案:

答案 0 :(得分:2)

尝试:

for i in finalschema:
    i.update({"type":'string'}) #all types will always be string
    if i['name'] == 'attr':
        i.update({'fields':finalschemanested})
  • 注意:由于错误状态在迭代对象时不要尝试更新dict。

答案 1 :(得分:0)

禁止在迭代其键/值对的同时修改i,一种解决方法是仅迭代其键并更新i,如下所示:

for i in finalschema:
    i.update({"type":'string'})
    for val in i.keys():
        if i[val] == 'attr':
            i['fields'] = finalschemanested

但是,这在迭代时修改了dict,这不是一个好主意。如果有更好的方法来做您想做的事情,那么最好考虑一下重构。

在您的情况下,您根本不需要遍历i,并将代码更改为以下内容:

for i in finalschema:
    i["type"] = 'string'
    if i['name'] == 'attr':
        i['fields'] = finalschemanested

另一方面,您使代码容易陷入python陷阱:i.update({'fields': finalschemanested})将在要更新的每个字典中放置相同的finalschemanested对象。如果您多次执行此操作,则在两个不同的位置拥有相同的对象,这意味着修改一个位置会导致在另一个位置进行(可能是不需要的)修改。考虑使用copy模块:

from copy import deepcopy
... 
       i.update({'fields': deepcopy(finalschemanested)})
...

答案 2 :(得分:0)

迭代Dict并切换到相同的Dict不是一个好主意。请参阅:Christoph Zwerschke's blog.

您需要通过这种模式更改代码。列表和其他数据结构都是如此。在python2中,它永远不会显示为错误或警告,并且循环不断。 请参阅我的答案之一Raja Sakthiyan