Python 递归函数不递归

Python 递归函数不递归,python,recursion,Python,Recursion,我试图横穿一个由字典字典组成的树状结构,最底层的字典包含一个列表。以下是该结构的一个示例: Metabolism[currentL0][currentL1][currentL2][node] = [pathway1, pathway2, pathway3] 我使用此函数创建数据结构: Tree = lambda: defaultdict(Tree) Metabolism = Tree() 生成和填充数据结构的代码起作用。但是,我尝试使用递归生成器横切“树”,并返回顶键和与之相关的所有列表。发

我试图横穿一个由字典字典组成的树状结构,最底层的字典包含一个列表。以下是该结构的一个示例:

Metabolism[currentL0][currentL1][currentL2][node] = [pathway1, pathway2, pathway3]
我使用此函数创建数据结构:

Tree = lambda: defaultdict(Tree)
Metabolism = Tree()
生成和填充数据结构的代码起作用。但是,我尝试使用递归生成器横切“树”,并返回顶键和与之相关的所有列表。发电机功能通过
if is instance
测试工作。如果块打印出hi,它将进入
,并将正确的值分配给
,但是,随后它似乎会跳过递归调用并打印出
。为了测试这一点,我将
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
for x,y in walk_dict(Metabolism):
    pass
test
print
语句似乎确认函数没有递归。它会打印一个空行,后面跟有顶级字典键一样多的
hi
s和
bye
s。以下是一个输出示例:

<blank line>
hi
bye
hi
bye
hi
bye
hi
bye
hi
bye
hi
bye

一个相当基本的建议。你确定所有的压痕都是正确的吗?当制表符和空格混淆时,这种错误情况会经常出现

在某些编辑器中,除非将其配置为显示可见的间距,否则无法很好地看到它。我使用Geany编辑Python代码,并启用编辑器显示选项卡和空格,并使用“显示空白”选项


如果已将制表符编程为4个字符,则这尤其令人困惑。Python总是将制表符视为8个空格,但编辑器可能会将其显示为4。

对于递归函数,这样做是错误的。在递归函数中,当您直接调用-
walk_dict(v,depth+1,“recursive”)
-它只返回生成器对象并丢弃(因为您没有对它做任何操作)-它不会遍历函数

walk\u dict()
是一个generator函数,当您只调用
walk\u dict()
时,它将只返回生成器对象(不会遍历它)。让我们举一个例子-

>>> def func():
...     print("Hello")
...     yield 10
...
>>>
>>> func()
<generator object func at 0x006FF418>
>>> next(func())
Hello
10

我没有测试上面的代码,因为我没有其他代码来测试它,但是您可以尝试一下。

问题是当您进行递归调用时,您没有得到结果。替换此行:

         walk_dict(v,depth+1,"recursive")
         for item in walk_dict(v,depth+1,"recursive"):
             yield item
这一行:

         walk_dict(v,depth+1,"recursive")
         for item in walk_dict(v,depth+1,"recursive"):
             yield item
如果您运行的是Python 3,则可以使用
yield from
构造:

         yield from item in walk_dict(v,depth+1,"recursive"):
更新 回答你的问题,考虑下面的调用:

         walk_dict(v,depth+1,"recursive")

在原始代码中,只需调用
walk\u dict
,它将返回一个生成器。但是,您没有从该生成器中提取任何有用的列表并返回给调用者。

您好,Darwin,您是否可以在“d.items()中的k,v”和“if-isinstance(v,defaultdict):”的行之间添加一行“打印深度”。我在想,如果以“v”作为新dict的递归调用没有通过isinstace检查。另外,我也不确定给定的dict“d”中有多少个深度为“0”的键。skippy我添加了请求的代码,它打印了六次深度为“0”的
0
。深度0有六个键。奇怪!在将它传递给WalkgDIGT(V,深度+1,“递归”)之前,你还可以检查是否可以“打印V ItSe())。我只是好奇,因为考虑了例子是实例({},DICT)->在Python中返回true,即使空的DICT与Python DICT类进行比较。我只是仔细检查了制表符。完全正确。vim将四个空格显示为一个选项卡,但是,所有其他代码工作正常,因此vim必须只显示八个空格中的四个。我不确定我是否理解这一点。如果您只是
cat
程序,它的格式是否正确?根据缩进的样式建议,进一步研究它应该是四个空格,而不是八个空格。当我
cat
程序的每个缩进级别是四个空格时,我发现我的错误是没有在生成器上迭代(即调用next())以获得下一个值。然而,我不明白为什么需要
收益项目
。它只是把控制权还给了原来的发电机吗?