3

我有以下高度简化的结构

elements = [{"id": "1", "counts": [1, 2, 3]},
            {"id": "2", "counts": [4, 5, 6]}]

我希望能够构建,使用glom,形式的新字典{<id>: <counts[pos]>},例如pos = 2

{"1": 3, "2": 6}

或者一个元组列表/元组

[("1",3), ("2", 6)]

使用 adict 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)

这样,可以从外部控制从每个元素中提取的内容。

4

1 回答 1

3

要将id每个字典列表转换为 id-keyed 字典,您可以使用简单的字典理解:

{t["id"]: glom.glom(t, "counts.2") for t in elements}

或者,如果您想为此使用 glom,使用glom.Mergeglom.T

glom.glom(elements, glom.Merge([{T['id']: 'counts.2'}])))

为避免使用 lambda,您可以将pos参数插入到规范字符串中,例如'counts.%s' % pos.

于 2019-08-14T14:01:21.003 回答