我遇到了这个函数,它可以使字典变平:
def flatten(dictionnary, container=None):
if container is None:
container = []
for k, v in dictionnary.items():
container.append(k)
if v:
flatten(v, container)
return container
为了测试它,我创建了一个嵌套n
次的字典,如下所示:
nesteddict = {}
for i in range(n, 0, -1):
emptydict = {}
emptydict[i] = nesteddict
nesteddict = emptydict
当n
小于999时,函数工作,否则它会达到递归极限:
RecursionError: maximum recursion depth exceeded while calling a Python object
因此,经过一点搜索,似乎any recursive function can rewritten to iteration,但我不能看到它如何可以做的功能,我必须产生相同的结果。
我在玩这个的时候遇到的另一个奇怪的问题是,如果我尝试下面的n >= 998
代码:
nesteddict = {}
for i in range(n, 0, -1):
emptydict = {}
emptydict[i] = nesteddict
nesteddict = emptydict
print(nesteddict)
我得到递归错误:
RecursionError: maximum recursion depth exceeded while getting the repr of an object
这很奇怪,因为我在这里没有看到任何递归。
5条答案
按热度按时间guykilcj1#
你应该把项的迭代器保存在堆栈中,而不是把字典保存在堆栈中。
这样,您就可以在命令下恢复迭代器。
另外,因为你是按顺序暂停和恢复迭代器的执行,所以结果总是按照指令的顺序。
顺便说一下,@iBug,dicts是按照Python 3.7的规范排序的
lrpiutwd2#
从逻辑上讲,嵌套字典(和列表)是一种递归,所以如果你想避免逻辑递归,那是不可能的。
但是,由于递归只是递归,你可以保留一个自己的堆栈并在循环中模拟它:
这个函数很好地模拟了函数递归的行为,使用了一个自定义堆栈。
有一个潜在的缺点:从理论上讲,像这样的字典
应该被展平为
[1, 2, 3, 4, 5]
,而这种方法将给予[1, 2, 5, 3, 4]
。这很像图上的DFS搜索与BFS搜索。但是,因为dictionary是无序的,这应该不是什么大问题(除非你使用
collections.OrderedDict
),这就是为什么我说这是一个潜在的缺点。xu3bshqb3#
变平可以有不同的解释;如果您想将一个字典扁平化为一个带有点分隔键字典,那么这种方法可能会有效:
给定输入:
{'b': 2, 'a': 1, 'c': {'a': 1, 'b': [1, 2, 3]}, 'd': [1, 2, {'b': 1, 'a': 2}]}
输出为:
ddhy6vgd4#
你可以在这里使用pandas.json_normalize文档:https://pandas.pydata.org/docs/reference/api/pandas.json_normalize.html
dgjrabp25#
如果你想不使用递归来实现它,那是不可能的。
这里是RecursionError的解决方案。
基于doc of python.你可以使用
sys.getrecursionlimit()
来查看递归的限制。您也可以使用sys.setrecursionlimit()
来设置上限。