首页 > 解决方案 > 在嵌套结构上使用Glom,如何将顶级字典字段移动到字典列表中?

问题描述

这是一个关于Glom使用的问题(https://github.com/mahmoud/glom/

我有一本包含其他词典列表的词典。

{'date': '2020-01-01',
 'location': 'A',
 'items': [
     {'name': 'A', 'id': 'A1'},
     {'name': 'B', 'id': 'B1'},
     {'name': 'C', 'id': 'C1'}
]}

我想使用Glom将外部的全局字典字段“日期”和“位置”移动到项目的字典列表中。

这是我试图达到的最终结果

[
 {'name': 'A', 'id': 'A1', 'date': '2020-01-01', 'location': 'A'},
 {'name': 'B', 'id': 'B1', 'date': '2020-01-01', 'location': 'A'},
 {'name': 'C', 'id': 'C1', 'date': '2020-01-01', 'location': 'A'}
]

唉,当规范到达字典的“项目”时,其他值不再可访问,而是将 T 对象设置为内部值。

from glom import glom, T

def update_dict(x, other_dict):
    x.update({'date': other_dict['date'], 'location': other_dict['location']})  
    return x.copy()

spec = (T, 'items', [(lambda x: update_dict(x, T()))])

data = {'date': '2020-01-01',
       'location': 'A',
       'items': [{'name': 'A', 'id': 'A1'},
                 {'name': 'B', 'id': 'B1'},
                 {'name': 'C', 'id': 'C1'}]}

glom(data, spec)  # print this

返回

[{'name': 'A', 'id': 'A1', 'date': T()['date'], 'location': T()['location']},
 {'name': 'B', 'id': 'B1', 'date': T()['date'], 'location': T()['location']},
 {'name': 'C', 'id': 'C1', 'date': T()['date'], 'location': T()['location']}]

这是没用的。

使用常规 Python 代码更新字典并不难,但有没有办法在Glom规范中做到这一点?

标签: pythonglom

解决方案


诀窍是将目标也作为全局范围传递,这样,Assign命令就可以访问完整的目标。

from glom import S, glom, Assign, Spec

spec = ('items', 
        [Assign( 'date', Spec(S['date']))], 
        [Assign( 'location', Spec(S['location']))]
       )

target = {'date': '2020-04-01',
     'location': 'A',
     'items': [
         {'name': 'A', 'id': 'A1'},
         {'name': 'B', 'id': 'B1'},
         {'name': 'C', 'id': 'C1'}
    ]}

spec = Spec(('items', [Assign( 'date', Spec(S['date']))], [Assign( 'location', Spec(S['location']))]))

glom(target, spec, scope=target)

结果是

[{'name': 'A', 'id': 'A1', 'date': '2020-04-01', 'location': 'A'},
 {'name': 'B', 'id': 'B1', 'date': '2020-04-01', 'location': 'A'},
 {'name': 'C', 'id': 'C1', 'date': '2020-04-01', 'location': 'A'}]

推荐阅读