【问题标题】:returning from recursive function in python从python中的递归函数返回
【发布时间】:2014-03-18 23:35:36
【问题描述】:

我对编程有点缺乏经验,对返回函数的工作原理有点困惑。我正在尝试编写一个将函数映射到嵌套列表元素的程序。变量级别表示列表中嵌套级别的次数。我目前可以通过打印我的最终映射列表 totlist 来让程序运行:

def map_nested(listbasket, function, levels): #listbasket is the list that contains lists
    totlist=[] #this list will store the list after the function has been mapped to it
    for listelement in listbasket:

        if levels<=2: #once we get to the level that just contains a list of lists
            newlist=list(map(function,listelement)) 
            totlist.append(newlist) #add to final mapped list

        else:
            map_nested(listelement, function, levels-1) #recursively call for next level
    print(totlist)  

map_nested([[[1,2],[3,4]],[[5,6],[7,8]]], math.sqrt, 3) # my test function

相反,我想要返回 totlist 的东西,但我不知道该怎么做。每次我尝试返回它时,它只会返回一个空列表或列表的一部分。我觉得我已经尝试了我能想到的所有回报配置。

【问题讨论】:

  • 您是否尝试将print(totlist) 替换为return totlist
  • 您说它打印正确,如果您确实进行了替换,它将返回它正在打印的内容。您必须记住将该返回值分配给调用站点的变量并在那里打印出来。
  • 我实际上已经尝试过了。它没有用。当我打印变量时,它打印了 []
  • 哦,我明白你的意思了,最外面的调用打印也打印“[]”。根据您的描述,我认为您说的是正确的。由于递归性质,您必须将递归调用的返回值传播出去,Kaarel 的回答做得非常干净。
  • 你能解释一下 Kaarel 的第一个答案是如何工作的吗?我不明白如何在 totlist 后面附加一个将 totlist 设置为 0 的函数。

标签: python list recursion mapping return


【解决方案1】:

这将起作用:

import math

def map_nested(listbasket, function, levels): #listbasket is the list that contains lists
    totlist=[] #this list will store the list after the function has been mapped to it
    for listelement in listbasket:

        if levels<=2: #once we get to the level that just contains a list of lists
            newlist=list(map(function,listelement)) 
            totlist.append(newlist) #add to final mapped list
        else:
            totlist.append(map_nested(listelement, function, levels-1))
    return totlist

map_nested([[[1,2],[3,4]],[[5,6],[7,8]]], math.sqrt, 3) # my test function

或更简洁的解决方案:

import math

def map_nested(input, function):
    if type(input) is list:
        return [map_nested(e, function) for e in input]
    else:
        return function(input)

print map_nested([[[1,2],[3,4]],[[5,6],[7,8]]], math.sqrt)

这是递归地将map_nested 方法应用于层次结构中的每个列表。当递归到达列表中的元素时,它会应用原始调用中提供的函数。

请注意,这适用于任意深度嵌套的列表,也适用于不平衡的嵌套列表(例如,[1, 2, [3, 4]])。

【讨论】:

  • 谢谢,这正是我想要的。但是,我不确定我是否了解它的工作原理。似乎附加该函数最终会多次添加元素。你能解释一下这里发生了什么吗?
【解决方案2】:

我会让totlist 成为一个论点:

def map_nested(listbasket, function, levels, totlist=None):
    if totlist is None:
        totlist = []
    for listelement in listbasket:
        if levels <= 2:
            newlist = list(map(function, listelement)) 
            totlist.append(newlist) #add to final mapped list
        else:
            map_nested(listelement, function, levels-1, totlist)
    return totlist

现在:

>>> map_nested([[[1,2],[3,4]],[[5,6],[7,8]]], math.sqrt, 3)
[[1.0, 1.4142135623730951], 
 [1.7320508075688772, 2.0], 
 [2.23606797749979, 2.449489742783178], 
 [2.6457513110645907, 2.8284271247461903]]

如果您想简化(而不是手动传递关卡)并在进行过程中将嵌套变平,例如:

def map_nested_2(lst, f, out=None):
    if out is None:
        out = []
    for item in lst:
        if isinstance(item, list):
            map_nested_2(item, f, out)
        else:
            out.append(f(item))
    return out

愿意:

[1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.23606797749979, 
 2.449489742783178, 2.6457513110645907, 2.8284271247461903]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 2016-06-30
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多