Python 是否正在寻找可能更好的方法来使用glom获取嵌套数据?

Python 是否正在寻找可能更好的方法来使用glom获取嵌套数据?,python,nested,glom,Python,Nested,Glom,我有一个特别讨厌的stats对象,它来自一个我需要从中检索数据的系统(为了简洁起见,显示了许多stats条目中的两个) 目前,我在嵌套堆栈中多次使用.get方法,但本周末我听了《Python讨论》一书的作者的话,认为这对我来说可能是一个更干净的解决方案。它是这样的,因为这段代码使我在一个循环中拥有所有的数据,而没有疯狂的get方法层(上面的第一个示例,我今晚正在处理)。外键是长URL,内键是avg/current/max/desc stats = b.tm.sys.performances.al

我有一个特别讨厌的stats对象,它来自一个我需要从中检索数据的系统(为了简洁起见,显示了许多stats条目中的两个)

目前,我在嵌套堆栈中多次使用.get方法,但本周末我听了《Python讨论》一书的作者的话,认为这对我来说可能是一个更干净的解决方案。它是这样的,因为这段代码使我在一个循环中拥有所有的数据,而没有疯狂的get方法层(上面的第一个示例,我今晚正在处理)。外键是长URL,内键是avg/current/max/desc

stats = b.tm.sys.performances.all_stats.load()
for k, v in stats.entries.items():
    print('\n')
    spec = f'entries.{k}.nestedStats.entries'
    v_stats = glom(stats, spec)
    for k, v, in v_stats.items():
        spec = f'{k}.description'
        stat_vals = glom(v_stats, spec)
        print(f'{k}: {stat_vals}')
这将产生我需要的数据:

Average: 5
Current: 5
Max(since 2019_11_12T02:47:10Z): 5
Memory Used: TMM Memory Used

这就是说,我现在并不能真正控制数据,我只是在打印它。我不认为我正在摸索格洛姆的力量,我很好奇是否有人能给我举个例子来帮助我理解?最终目标是将所有这些数据平铺到一个包含4项词典的列表中。

首先,在尝试此操作之前,请确保glom已更新到当前版本19.11.0或更高版本

你所要求的,被glom的文档称为数据驱动的分配,而不是glom的优势

参见glom文档

要使其工作,您可能需要lambdas和/或常规Python代码

下面是我的工作尝试,将示例行复制到变量d

from glom import glom, Call, T, Iter

d = { ... }  # put your example lines into this dictionary.

def get_desc(subdict):
    return {k: v.get('description', None) 
            for k,v in subdict[1]['nestedStats']['entries'].items()}

spec = (Call(list, args=(T.items(),) ), Iter().map(get_desc).all())

result = glom(d, spec)

print(result)
导致

[
{'Average': '5', 'Current': '5', 'Max(since 2019_11_12T02:47:10Z)': '5', 'Memory Used': 'TMM Memory Used'}, 
{'Average': '9', 'Current': '10', 'Max(since 2019_11_12T02:47:10Z)': '53', 'System CPU Usage': 'Utilization'}
]
更新 下面的版本得到了相同的结果,但是避免了对helper函数的需要

规范的作用是:

  • 调用将外部dict转换为元组列表
  • 国际热核聚变实验堆在清单上循环。对于每个项目:
  • 取元组的第二个元素
  • 获取nestedStats.entries(这是另一个dict)
  • 调用将此dict转换为元组列表
  • 将此列表转换为带有键和说明的DICT列表
  • 将目录列表合并为一个目录
  • 从迭代中获取所有结果
我建议尝试一下,删除部分规范,看看会发生什么

from glom import glom, Call, T, Iter, merge

# d = { ... }  # put your example lines into this dictionary.

spec = (
    Call(list, args=(T.items(),)),
    Iter(
        (
            T[1],
            "nestedStats.entries",
            Call(list, args=(T.items(),)),
            [{T[0]: (T[1], "description")}],
            merge,
        )
    ).all(),
)

result = glom(d, spec)

print(result)

那很有帮助,谢谢!我会在一段时间内消化这一点,因为我很有信心我可以离开几天,永远不会回到这个解决方案。你提到这不是glom的强项,你能推荐另外一个更适合实现这一点的软件包吗?@JasonRahm抱歉,没有更好的了。我个人对glom非常感兴趣(我花了很多时间反复阅读这些文档),所以我的建议是一次又一次地尝试,直到它点击为止。仍然让我头疼的是
T
对象的使用,但是你可以用它代替lambda和常规python函数,因此glom即使没有它也很有用。@JasonRahm更新了一个完整的示例,不再需要helper/lambda函数。
from glom import glom, Call, T, Iter, merge

# d = { ... }  # put your example lines into this dictionary.

spec = (
    Call(list, args=(T.items(),)),
    Iter(
        (
            T[1],
            "nestedStats.entries",
            Call(list, args=(T.items(),)),
            [{T[0]: (T[1], "description")}],
            merge,
        )
    ).all(),
)

result = glom(d, spec)

print(result)