寻找可能更好的方法来使用 glom 获取嵌套数据?
Looking for the likely better way to get at nested data with glom?
我有一个来自系统的特别讨厌的统计对象,我需要从中检索数据(为简洁起见,显示了许多统计条目中的两个)。
'https://localhost/mgmt/tm/sys/performance/all-stats/TMM%20Memory%20Used': {'nestedStats': {'entries': {'Average': {'description': '5'},
'Current': {'description': '5'},
'Max(since 2019_11_12T02:47:10Z)': {'description': '5'},
'Memory Used': {'description': 'TMM '
'Memory '
'Used'}}}},
'https://localhost/mgmt/tm/sys/performance/all-stats/Utilization': {'nestedStats': {'entries': {'Average': {'description': '9'},
'Current': {'description': '10'},
'Max(since 2019_11_12T02:47:10Z)': {'description': '53'},
'System CPU Usage': {'description': 'Utilization'}}}}}
目前,我在嵌套堆栈中多次使用 .get 方法,但本周末我在 Talk Python 上听 glom module 的作者讲话,认为这可能更清晰我的解决方案。确实如此,正如这段代码所做的那样,我将所有数据都放在一个循环中,而没有疯狂的 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
就是说,此时我无法真正控制数据,我只是打印出来。我不认为我只是在摸索 glom 的力量,并且很好奇是否有人可以指出一个有助于我理解的例子?最终目标是将所有这些数据扁平化为一个包含 4 个条目的字典列表。
首先,在尝试之前,请确保 glom 已更新到当前版本 19.11.0 或更高版本。
glom 的文档将您要求的称为 Data-Driven-Assignment,而不是 glom 的强度。
查看 glom 文档 here
要使其正常工作,您可能需要 lambdas and/or 常规 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'}
]
更新
下面的版本得到相同的结果,但避免了对辅助函数的需要。
规范的作用:
- 调用将外部字典转换为元组列表
- Iter 遍历列表。对于每个项目:
- 取元组的第二个元素
- get nestedStats.entries(这是另一个字典)
- Call 把这个 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)
我有一个来自系统的特别讨厌的统计对象,我需要从中检索数据(为简洁起见,显示了许多统计条目中的两个)。
'https://localhost/mgmt/tm/sys/performance/all-stats/TMM%20Memory%20Used': {'nestedStats': {'entries': {'Average': {'description': '5'},
'Current': {'description': '5'},
'Max(since 2019_11_12T02:47:10Z)': {'description': '5'},
'Memory Used': {'description': 'TMM '
'Memory '
'Used'}}}},
'https://localhost/mgmt/tm/sys/performance/all-stats/Utilization': {'nestedStats': {'entries': {'Average': {'description': '9'},
'Current': {'description': '10'},
'Max(since 2019_11_12T02:47:10Z)': {'description': '53'},
'System CPU Usage': {'description': 'Utilization'}}}}}
目前,我在嵌套堆栈中多次使用 .get 方法,但本周末我在 Talk Python 上听 glom module 的作者讲话,认为这可能更清晰我的解决方案。确实如此,正如这段代码所做的那样,我将所有数据都放在一个循环中,而没有疯狂的 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
就是说,此时我无法真正控制数据,我只是打印出来。我不认为我只是在摸索 glom 的力量,并且很好奇是否有人可以指出一个有助于我理解的例子?最终目标是将所有这些数据扁平化为一个包含 4 个条目的字典列表。
首先,在尝试之前,请确保 glom 已更新到当前版本 19.11.0 或更高版本。
glom 的文档将您要求的称为 Data-Driven-Assignment,而不是 glom 的强度。
查看 glom 文档 here
要使其正常工作,您可能需要 lambdas and/or 常规 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'}
]
更新
下面的版本得到相同的结果,但避免了对辅助函数的需要。
规范的作用:
- 调用将外部字典转换为元组列表
- Iter 遍历列表。对于每个项目:
- 取元组的第二个元素
- get nestedStats.entries(这是另一个字典)
- Call 把这个 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)