python - 如何从嵌套字典的键构建路径?

标签 python python-3.x

我正在编写一个脚本,通过 MQTT 网络广播大量数据流。我正在尝试将嵌套字典的键转换为一个字符串,然后我可以将其用作 MQTT 广播 channel 。数据每秒都进来,已经格式化为嵌套的字典,如下所示:

my_dict = { 'stream1': { 'dataset1': { 'value1': 123.4}},
                         'dataset2': { 'value1': 123.4,
                                       'value2': 567.8},
            'stream2': { 'dataset3': { 'value4': 910.2}},
            'stream3': {               'value5': 'abcd'}}

我将它缩进以增加可读性,额外的空格不在实际数据中。如您所见,它有多个级别,并非所有级别都具有相同数量的值,并且某些值键是重复的。此外,一个级别比其他级别更浅,但如果这使问题更容易解决,我可以轻松地将其设置为与其他级别相同的深度。

上面的 dict 应该提供这样的输出:
("stream1/dataset1/value1", "stream1/dataset2/value1", ..., "stream3/value5")

等等。

我觉得递归可能是一个很好的解决方案,但我不确定如何在我通过结构时维护有序的键列表,以及确保我点击结构中的每个项目,为每个基本级别的项目(注意没有“stream1/dataset1”)。

这是我到目前为止的代码:
my_dict = { as defined above }

def get_keys(input_dict, path_list, current_path):
    for key, value in input_dict.items():
        if isinstance(value, dict):
            current_path += value
            get_keys(value, path_list, current_path)
        else:
            path = '/'.join(current_path)
            path_list.append(path)

my_paths = []
cur_path = []
get_keys(my_dict, my_paths, cur_path)
[print(p) for p in my_paths]

最佳答案

这是使用 yield 的绝佳机会把你的函数变成一个生成器。生成器可以产生一大堆项目,并且表现得非常像列表或其他可迭代对象。调用者循环其返回值并在每次迭代中获得一个产生的项目,直到函数返回。

def get_keys(input_dict):
    for key, value in input_dict.items():
        if isinstance(value, dict):
            for subkey in get_keys(value):
                yield key + '/' + subkey
        else:
            yield key

for key in get_keys(my_dict):
    print(key)

内外for循环每个值要么是字典要么是普通值。如果它是一个普通值,只需生成 key 。如果它是一个 dict,则迭代它并在前面加上 key + '/'到每个子键。

好处是你不必维护任何状态。 path_listcurrent_path消失了。 get_keys()简单地一一产生字符串和 yield语句和递归循环使键的扁平化自然抖动。
stream1/dataset1/value1
dataset2/value1
dataset2/value2
stream2/dataset3/value4
stream3/value5

关于python - 如何从嵌套字典的键构建路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55526348/

相关文章:

python - Airflow:如何将 PyMySQL 与 MySQL Hook 结合使用?

python - Pandas 在 groupby 中设置值

python - 在同一函数中的子进程调用之前运行 python 命令?

python - 在Python中根据父/子列表构建树

python - 使用 ThreadPoolExecutor 的 Map 传递多个值

python - 修改使用 from ... import * 导入的模块中的变量

python - 排序()返回无

python - 如何使用 python kubernetes api 按标签获取 pod?

python - pyserial:循环波特率

python - 将函数返回元组解包为键值对