无论如何将我的递归函数更改为 return 一个值并且没有全局变量?

Anyway to change my recursive function to return a value and be without global variables?

我学python也就一个月左右。这是我为 Pygame 编写的一个递归函数,用于在多边形中找到正确的路径而不用撤退。这里只是一个五边形,(0,1,2,3,4)是顶点数。

但是,此代码适用于两个全局变量:

last_poses = {}
route_all = []

这意味着我每次调用它时都必须初始化这两个变量。我也尝试 return 所有可用的路线,但它没有正常工作。

这个结果来自全局变量,正确:

[{0: 0, 1: 4, 2: 3, 3: 2, 4: 1, 5: 0}, {0: 0, 1: 4, 2: 3, 3: 2, 4: 1, 5: 0}]

此结果来自 return 值:

[{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 0}]

我的问题是 return 没有全局变量的正确值。谁能帮我解决这个问题,我真的很感激。

legal_action = ((4,1),(0,2),(1,3),(2,4),(0,3))

def route_cal(start_pos, steps):
    global last_poses,route_all
    last_poses[steps] = start_pos
    steps -= 1
    dest_all = list(legal_action[start_pos])

    if len(last_poses) >= 2:
        for i in dest_all:
            if i == last_poses[steps+2]:
                dest_all.remove(i)
    if steps > 0:
        for pos in dest_all:
            # route_cal(pos,steps)
            return route_cal(pos,steps)
    elif steps == 0:
        last_poses[steps] = dest_all[0]
        route_all.append(last_poses)
        return route_all
    # return route_all

last_poses = {}
route_all = []
# route_cal(0, 5)
# print route_all

routelines = route_cal(0,5)
print routelines

Circuit of my game

最简单的答案是使用非本地而不是全局。这是一样的,但变量在父范围内而不是全局范围内。

但是,对于您的示例,该函数的父作用域似乎是全局作用域,因此它不会改变任何内容。

更正确但更困难的答案是如果你想摆脱外部变量的使用,你将不得不将值作为参数传递给你的函数或者return一个包含您当前的全局变量和原始 return 变量。

This 问题可能会帮助您入门。

您有一些 options.One 正在使用可选参数。看起来您可以使用 route_all 作为可选参数。

例如

def route_cal(start_pos, steps, route_all = {}):

请记住,可选参数会初始化一次(第一次调用函数时)。

另一种方法是摆脱 dest_all 和 last_poses,只使用一个变量,route_all,并将到达多边形中的每个点的每个人附加到它,并且只有return那个点。

return [route_all] + [recursive_call_here]

您也可以考虑不使用 legal_actions 变量,并根据您所在的步骤编号根据需要创建 "neighbors" 值。

还有其他方法可以最大限度地减少您的问题,我建议将此问题移至 Code Review 部分以更深入地了解您的代码。例如,我会尽量避免使用如此多的循环,而是使用一个公式来计算 "neighbors" 递归通过每个步骤时。此外,通过确保您不访问不存在的内容来防止达到索引超出范围异常 and/or KeyError 异常。

根据我之前的评论,这是一种遍历多边形的简单迭代方法。它似乎给出了您指定的内容,而没有使用全局变量甚至递归。这就是您所需要的吗?

def route_cal(start_node, move_list):
    # For each step in the circuit
    here = start_node
    path = [here]
    for step in range(len(move_list)):
        # Find any legal move to an adjacent vertex
        dest = move_list[here]
        for here in dest:
            if here not in path:    # Don't repeat a vertex
                path.append(here)
                break
    path.append(start_node)

    # Now that we've found the full circuit, build a dictionary in each direction
    path_len = len(path)
    forward = {n: path[n] for n in range(path_len)}
    reverse = {n: path[path_len-n-1] for n in range(path_len)}
    return [forward, reverse]


legal_action = ((4,1), (0,2), (1,3), (2,4), (0,3))
print route_cal(0, legal_action)