【问题标题】:Recursion return wrong list of lists递归返回错误的列表列表
【发布时间】:2020-02-23 05:48:27
【问题描述】:

我试图解决一个问题,其中一部分是找到从 (0, 0) 到二维数组最右边的所有路径。这是我的代码:

def route_finder_helper(x, y, current_path, filler, list_of_lists):

    current_path[filler] = (x, y)

    if x == 0 and y == 0:
        print(current_path)
        list_of_lists.append(current_path)
        return list_of_lists

    if x == 0:
        return route_finder_helper(x, y - 1, current_path, filler - 1, list_of_lists)

    if y == 0:
        return route_finder_helper(x - 1, y, current_path, filler - 1, list_of_lists)

    return route_finder_helper(x-1, y, current_path, filler - 1, list_of_lists) + \
           route_finder_helper(x, y-1, current_path, filler - 1, list_of_lists)

其中 x 和 y 是当前坐标,current_path 是当前路径的元组列表,filler 是要更改的列表位置的索引,list_of_lists 应该是所有路径。但是,当我运行这个程序并打印返回值时,我得到了这个输出:

 [(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)]
 [(0, 0), (0, 1), (1, 1), (1, 2), (2, 2)]
 [(0, 0), (1, 0), (1, 1), (1, 2), (2, 2)]
 [(0, 0), (0, 1), (1, 1), (2, 1), (2, 2)]
 [(0, 0), (1, 0), (1, 1), (2, 1), (2, 2)]
 [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)]
 [[(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)]]

所以我得到了正确的路径,但我不知道如何将它们保存到列表列表中。有人可以帮我吗?

这就是我调用函数的方式:

x_coordinate = coordinates[0]  
y_coordinate = coordinates[1]  
path_length = (x_coordinate + 1) + (y_coordinate + 1) - 1  
start_filling = path_length - 1  
current_path = [0] * path_length  
paths = route_finder_helper(x_coordinate, y_coordinate, current_path, 
start_filling, [])

这是它应该返回的:

[[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)],[(0, 0), (0, 1), (1, 1), (1, 2), (2, 2)], [(0, 0), (1, 0), (1, 1), (1, 2), (2, 2)], [(0, 0), (0, 1), (1, 1), (2, 1), (2, 2)], [(0, 0), (1, 0), (1, 1), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)]]

【问题讨论】:

  • 你能提供一个关于如何调用函数的例子吗?电流输出有什么问题?我猜最后一个(列表列表)不应该在那里?
  • x_coordinate = 坐标[0]; y_coordinate = 坐标[1]; path_length = (x_coordinate + 1) + (y_coordinate + 1) - 1; start_filling = path_length - 1;当前路径 = [0] * 路径长度;路径 = route_finder_helper(x_coordinate, y_coordinate, current_path, start_filling, [])
  • 我不能把它换行,但我希望你能看到
  • 是的,我明白,最好是编辑问题并将其添加到那里,但现在还可以。我很快就要睡觉了,我今晚可能没有时间“解决”这个问题。
  • 感谢您编辑问题。我改变了答案,我想我解决了:)

标签: python list recursion


【解决方案1】:

这是正确答案:

def route_finder_helper(x, y, current_path, filler, list_of_lists):

    current_path[filler] = (x, y)

    if x == 0 and y == 0:
        return list_of_lists + [current_path[:]]

    if x == 0:
        return route_finder_helper(x, y - 1, current_path, filler - 1, list_of_lists)

    if y == 0:
        return route_finder_helper(x - 1, y, current_path, filler - 1, list_of_lists)

    return route_finder_helper(x-1, y, current_path, filler - 1, list_of_lists) + \
           route_finder_helper(x, y-1, current_path, filler - 1, list_of_lists)

x_coordinate = 2
y_coordinate = 2
path_length = (x_coordinate + 1) + (y_coordinate + 1) - 1
start_filling = path_length - 1
current_path = [0] * path_length
paths = route_finder_helper(x_coordinate, y_coordinate, current_path, start_filling, [])
print(paths)

输出:

[[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)], 
[(0, 0), (0, 1), (1, 1), (1, 2), (2, 2)], 
[(0, 0), (1, 0), (1, 1), (1, 2), (2, 2)], 
[(0, 0), (0, 1), (1, 1), (2, 1), (2, 2)], 
[(0, 0), (1, 0), (1, 1), (2, 1), (2, 2)], 
[(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)]]

这里的更正是:

return list_of_lists + [current_path[:]]

我使用current_path[:]添加一个副本

【讨论】:

    【解决方案2】:

    代码的逻辑是正确的,您遇到的问题是您正在处理一个可变项目的列表。这意味着每个引用列表的变量都会在您仅更改一个变量时获得更新的列表:

    a = [1, 2, 3]
    b = a
    a[0] = -1
    print(b)
    >>> [-1, 2, 3]
    

    当您附加到list_of_lists 时,您的代码中也会发生类似的情况。只需将附加更改为:

    # return list_of_lists.append(current_path)  <- old code
    return list_of_lists + [current_path]  <- new code
    

    这保证了每次代码结束时您都会启动一个新列表,而不是附加到代码的其他部分也有引用的列表。

    如果这对您来说是 Python 中的一个新概念,那么有很多不错的博客比我更详细地解释了这一点,例如here

    完整代码:

    def route_finder_helper(x, y, current_path, filler, list_of_lists):
    
        current_path[filler] = (x, y)
    
        if x == 0 and y == 0:
            return list_of_lists + [current_path]
    
        if x == 0:
            return route_finder_helper(x, y - 1, current_path, filler - 1, list_of_lists)
    
        if y == 0:
            return route_finder_helper(x - 1, y, current_path, filler - 1, list_of_lists)
    
        return route_finder_helper(x-1, y, current_path, filler - 1, list_of_lists) + \
               route_finder_helper(x, y-1, current_path, filler - 1, list_of_lists)
    
    x_coordinate = 2
    y_coordinate = 2
    path_length = (x_coordinate + 1) + (y_coordinate + 1) - 1
    start_filling = path_length - 1
    current_path = [0] * path_length
    paths = route_finder_helper(x_coordinate, y_coordinate, current_path, start_filling, [])
    print(paths)
    >>> [[(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)]]
    

    【讨论】:

    • 不,这是不正确的。我需要将每条路径保存为元组列表,在这种情况下,一旦达到目标点 (2,2),我需要将其添加到所有路径的列表中,但在递归之后,该列表会损坏。
    • 感谢您的回答。但是,当我运行它时,它仍然返回相同的列表。
    • @Augustas,你确定吗?我再次检查了我的电脑,它工作正常。我添加了“完整”代码
    • 这很有趣。我会在晚上再试一次。非常感谢
    • 您显示的输出是相同列表的列表。将此与 OP 在问题末尾声明的所需输出进行比较。
    猜你喜欢
    • 2014-01-18
    • 2020-01-22
    • 1970-01-01
    • 2013-04-24
    • 2021-05-07
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    相关资源
    最近更新 更多