使用 glom 将字典列表的字段提取到新字典中
Extracting fields of a list of dictionaries into a new dictionary using glom
我有以下高度简化的结构
elements = [{"id": "1", "counts": [1, 2, 3]},
{"id": "2", "counts": [4, 5, 6]}]
我希望能够使用 glom
构建 {<id>: <counts[pos]>}
形式的新词典,例如pos = 2
:
{"1": 3, "2": 6}
或者 list/tuple 个元组
[("1",3), ("2", 6)]
使用dict comprehension
很简单,但数据结构比较复杂,我想动态指定要提取的内容。前面的例子是我想要实现的最简单的事情。
经过一段时间我设法解决了如下问题
from glom import glom, T
elements = [{"id": "1", "counts": [1,2,3]},{"id": "2", "counts": [4,5,6]}]
def extract(elements, pos):
extracted = glom(elements, ({"elements": [lambda v: (v["id"], v["counts"][pos])]}, T))
return dict(extracted["elements"])
但这需要调用 dict
。跳过字典间接寻址的细微变化是
def extract(elements, pos):
extracted = glom(elements, (([lambda v: {v["id"]: v["counts"][pos]}]), T))
return {k: v for d in extracted for k, v in d.items()}
现在,我可以使用 merge
函数调用 glom
调用
的返回值
def extract(elements, pos):
return merge(glom(elements, (([lambda v: {v["id"]: v["counts"][pos]}]), T)))
我对此比较满意,但是有更好的方法吗?更好的意思是构建一个更清洁的可调用规范?最终,我希望能够在运行时以用户友好的方式定义字典的值,即 v["counts"][pos]
.
这个想法的一个改进是使用一个可调用对象来调用内部字典的值
def counts_position(element, **kwargs):
return element["counts"][kwargs["pos"]]
def extract(elements, func, **kwargs):
return merge(glom(elements, (([lambda v: {v["id"]: func(v, **kwargs)}]), T)))
extract(values, counts_position, pos=2)
有了这个,可以从外部控制从每个元素开始提取的内容。
要将每个带有 id
的字典列表转换为以 id 为键的字典,您可以使用简单的字典理解:
{t["id"]: glom.glom(t, "counts.2") for t in elements}
或者,如果你想为此使用 glom,:
glom.glom(elements, glom.Merge([{T['id']: 'counts.2'}])))
为了避免 lambda,您可以将 pos
参数插入到规范字符串中,例如'counts.%s' % pos
.
我有以下高度简化的结构
elements = [{"id": "1", "counts": [1, 2, 3]},
{"id": "2", "counts": [4, 5, 6]}]
我希望能够使用 glom
构建 {<id>: <counts[pos]>}
形式的新词典,例如pos = 2
:
{"1": 3, "2": 6}
或者 list/tuple 个元组
[("1",3), ("2", 6)]
使用dict comprehension
很简单,但数据结构比较复杂,我想动态指定要提取的内容。前面的例子是我想要实现的最简单的事情。
经过一段时间我设法解决了如下问题
from glom import glom, T
elements = [{"id": "1", "counts": [1,2,3]},{"id": "2", "counts": [4,5,6]}]
def extract(elements, pos):
extracted = glom(elements, ({"elements": [lambda v: (v["id"], v["counts"][pos])]}, T))
return dict(extracted["elements"])
但这需要调用 dict
。跳过字典间接寻址的细微变化是
def extract(elements, pos):
extracted = glom(elements, (([lambda v: {v["id"]: v["counts"][pos]}]), T))
return {k: v for d in extracted for k, v in d.items()}
现在,我可以使用 merge
函数调用 glom
调用
def extract(elements, pos):
return merge(glom(elements, (([lambda v: {v["id"]: v["counts"][pos]}]), T)))
我对此比较满意,但是有更好的方法吗?更好的意思是构建一个更清洁的可调用规范?最终,我希望能够在运行时以用户友好的方式定义字典的值,即 v["counts"][pos]
.
这个想法的一个改进是使用一个可调用对象来调用内部字典的值
def counts_position(element, **kwargs):
return element["counts"][kwargs["pos"]]
def extract(elements, func, **kwargs):
return merge(glom(elements, (([lambda v: {v["id"]: func(v, **kwargs)}]), T)))
extract(values, counts_position, pos=2)
有了这个,可以从外部控制从每个元素开始提取的内容。
要将每个带有 id
的字典列表转换为以 id 为键的字典,您可以使用简单的字典理解:
{t["id"]: glom.glom(t, "counts.2") for t in elements}
或者,如果你想为此使用 glom,
glom.glom(elements, glom.Merge([{T['id']: 'counts.2'}])))
为了避免 lambda,您可以将 pos
参数插入到规范字符串中,例如'counts.%s' % pos
.