使用Python递归函数从字典中获取数据

3
我已经创建了一个递归函数,从字典中获取数据。该字典由键组成,每个键都有一个键列表,依次进行。因此,当我提供一个键输入时,我需要获取键的扁平列表。
我的字典:
data = {"p": ["s1", "s2", "s3", "s4"],
        "s1": ["s1s1", "s1s2"],
        "s2": [],
        "s3": [],
        "s4": [],
        "s1s1": [],
        "s1s2": ["s1s2s1"],
        "s1s2s1": []
        }

我的功能:
def get_data(key):
    items = data[key]
    if items:
        for key in items:
            items += get_data(key)
    return items

当我调用get_data("p")时,它会返回

['s1', 's2', 's3', 's4', 's1s1', 's1s2', 's1s2s1', 's1s2s1']

但是预期的输出是:
['s1', 's2', 's3', 's4', 's1s1', 's1s2', 's1s2s1']

提前感谢任何帮助...

items 是什么? - Rakesh
问题已更新 - Muthu Kumar
@MuthuKumar,它们存在的列表顺序是否重要? - Devanshu Misra
@MuthuKumar 请参考所提供的答案。 - Devanshu Misra
2个回答

3
问题出在这些行代码中 -
for key in items:
    items += get_data(key)

在迭代过程中,你正在修改项目。 因此,在最后一次迭代中,你的items以相同的键多次结束; 你可以添加一个日志记录语句来查看使用哪个键调用了get_data

你想要单独获取所有新项目,然后在迭代完成后更新项目-

new_items = []
for key in items:
    new_items += get_data(key)
items += new_items

0

这里有一段代码可以帮助你实现你想要的功能。获取唯一项目的常见方法是使用set。集合是不重复对象的无序集合。要从任何可迭代对象创建一个集合,只需将其传递给内置的set()函数即可。如果您稍后需要一个真正的列表,同样可以将集合传递给list()函数。

data = {"p": ["s1", "s2", "s3", "s4"],
        "s1": ["s1s1", "s1s2"],
        "s2": [],
        "s3": [],
        "s4": [],
        "s1s1": [],
        "s1s2": ["s1s2s1"],
        "s1s2s1": []
        }

def get_data(key):
    items = data[key]
    if items:
        for keys in items:
            items += get_data(keys)
    return list(set(items))

print(get_data("p"))

输出:

['s3', 's1s1', 's1', 's1s2', 's2', 's1s2s1', 's4']

更新:一种保持顺序的方法只需要两行代码:

from collections import OrderedDict
return OrderedDict((x, True) for x in items).keys()

将给定解决方案中的return行替换为Update: Solution中的return行,您将得到一个有序列表。

输出:

odict_keys(['s1', 's2', 's3', 's4', 's1s1', 's1s2', 's1s2s1'])

使用list()函数与获得的输出一起,可以得到以下列表:
['s1', 's2', 's3', 's4', 's1s1', 's1s2', 's1s2s1']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接