首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >递归函数不递归

递归函数不递归
EN

Stack Overflow用户
提问于 2015-07-06 04:39:57
回答 3查看 149关注 0票数 1

我正试图横越一个树形结构,这个结构是由一本字典组成的,字典的最低层包含一个列表。下面是该结构的一个示例:

代码语言:javascript
运行
复制
Metabolism[currentL0][currentL1][currentL2][node] = [pathway1, pathway2, pathway3]

我使用这个函数来创建数据结构:

代码语言:javascript
运行
复制
Tree = lambda: defaultdict(Tree)
Metabolism = Tree()

生成和填充数据结构的代码可以工作。但是,我试图使用递归生成器横越“树”,并返回顶部键和与其相关的所有列表。生成器功能通过if isinstance测试完成。它进入if块打印hi并将正确的值分配给key,但是,它似乎跳过递归调用并打印bye。为了测试这一点,我将print key语句放在函数的顶部,并在递归调用中将key设置为recursive,以便print key语句应该打印单词recursive,但没有。

代码语言:javascript
运行
复制
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语句似乎确认该函数不是递归的。它打印一个空行,后面跟着相同数量的hibyes,因为有顶级字典键。下面是输出的一个示例:

代码语言:javascript
运行
复制
<blank line>
hi
bye
hi
bye
hi
bye
hi
bye
hi
bye
hi
bye

最后,下面是调用生成器函数的代码:

代码语言:javascript
运行
复制
for x,y in walk_dict(Metabolism):
    pass
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-07-06 05:25:24

问题是,当您进行递归调用时,没有产生结果。替换这一行:

代码语言:javascript
运行
复制
         walk_dict(v,depth+1,"recursive")

用这一行:

代码语言:javascript
运行
复制
         for item in walk_dict(v,depth+1,"recursive"):
             yield item

如果您正在运行Python3,可以使用yield from构造:

代码语言:javascript
运行
复制
         yield from item in walk_dict(v,depth+1,"recursive"):

更新

要回答您的问题,请考虑以下调用所做的事情:

代码语言:javascript
运行
复制
         walk_dict(v,depth+1,"recursive")

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

票数 1
EN

Stack Overflow用户

发布于 2015-07-06 04:54:02

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

walk_dict()是一个遗传学函数,当您只调用walk_dict()时,它将只返回生成器对象(它不会遍历它)。让我们举个例子-

代码语言:javascript
运行
复制
>>> def func():
...     print("Hello")
...     yield 10
...
>>>
>>> func()
<generator object func at 0x006FF418>
>>> next(func())
Hello
10

正如您所看到的,仅仅调用生成器函数什么也不做,只有当您迭代它(或调用next())时,才实际调用生成器函数。

这也是您需要在代码中执行的工作,您需要递归地遍历walk_dict(),并在每个级别上生成结果。

例子-

代码语言:javascript
运行
复制
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

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

票数 1
EN

Stack Overflow用户

发布于 2015-07-06 04:47:15

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

在某些编辑器中,您无法很好地看到它,除非您将它们配置为明显地显示间距。我使用Geany编辑Python代码,并使编辑器能够显示选项卡和空格,并使用“显示空白”选项。

如果您已经将Tabs编程为4个字符,这将特别令人困惑。Python总是考虑Tab 8空格,但编辑器可能会将其显示为4。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31237883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档