我正试图横越一个树形结构,这个结构是由一本字典组成的,字典的最低层包含一个列表。下面是该结构的一个示例:
Metabolism[currentL0][currentL1][currentL2][node] = [pathway1, pathway2, pathway3]
我使用这个函数来创建数据结构:
Tree = lambda: defaultdict(Tree)
Metabolism = Tree()
生成和填充数据结构的代码可以工作。但是,我试图使用递归生成器横越“树”,并返回顶部键和与其相关的所有列表。生成器功能通过if isinstance
测试完成。它进入if
块打印hi
并将正确的值分配给key
,但是,它似乎跳过递归调用并打印bye
。为了测试这一点,我将print key
语句放在函数的顶部,并在递归调用中将key
设置为recursive
,以便print key
语句应该打印单词recursive
,但没有。
def walk_dict(d,depth=0,key=""):
print key
for k,v in d.items():
if isinstance(v, defaultdict):
print "hi"
if depth == 0:
key = k
walk_dict(v,depth+1,"recursive")
print "bye"
else:
yield key, v
测试print
语句似乎确认该函数不是递归的。它打印一个空行,后面跟着相同数量的hi
和bye
s,因为有顶级字典键。下面是输出的一个示例:
<blank line>
hi
bye
hi
bye
hi
bye
hi
bye
hi
bye
hi
bye
最后,下面是调用生成器函数的代码:
for x,y in walk_dict(Metabolism):
pass
发布于 2015-07-06 05:25:24
问题是,当您进行递归调用时,没有产生结果。替换这一行:
walk_dict(v,depth+1,"recursive")
用这一行:
for item in walk_dict(v,depth+1,"recursive"):
yield item
如果您正在运行Python3,可以使用yield from
构造:
yield from item in walk_dict(v,depth+1,"recursive"):
更新
要回答您的问题,请考虑以下调用所做的事情:
walk_dict(v,depth+1,"recursive")
在原始代码中,只需调用walk_dict
,它将返回一个生成器。但是,您没有从生成器中提取任何有用的列表并返回给调用者。
发布于 2015-07-06 04:54:02
对于递归函数来说,这样做是错误的。在递归函数中,当直接调用- walk_dict(v,depth+1,"recursive")
时-它只返回生成器对象并丢弃(因为您没有对它做任何事情)-它将不会遍历该函数。
walk_dict()
是一个遗传学函数,当您只调用walk_dict()
时,它将只返回生成器对象(它不会遍历它)。让我们举个例子-
>>> def func():
... print("Hello")
... yield 10
...
>>>
>>> func()
<generator object func at 0x006FF418>
>>> next(func())
Hello
10
正如您所看到的,仅仅调用生成器函数什么也不做,只有当您迭代它(或调用next())时,才实际调用生成器函数。
这也是您需要在代码中执行的工作,您需要递归地遍历walk_dict()
,并在每个级别上生成结果。
例子-
def walk_dict(d,depth=0,key=""):
print key
for k,v in d.items():
if isinstance(v, defaultdict):
print "hi"
if depth == 0:
key = k
for i,j in walk_dict(v,depth+1,"recursive"):
yield i, j
print "bye"
else:
yield key, v
我还没有测试上面的代码,因为我没有剩下的代码来测试它,但是您可以尝试它。
发布于 2015-07-06 04:47:15
一个相当基本的建议。你确定所有的凹痕都是正确的吗?当制表符和空格混合时,这种类型的错误情况经常出现。
在某些编辑器中,您无法很好地看到它,除非您将它们配置为明显地显示间距。我使用Geany编辑Python代码,并使编辑器能够显示选项卡和空格,并使用“显示空白”选项。
如果您已经将Tabs编程为4个字符,这将特别令人困惑。Python总是考虑Tab 8空格,但编辑器可能会将其显示为4。
https://stackoverflow.com/questions/31237883
复制相似问题