无论如何要改变我的递归函数以返回一个值而没有全局变量?

时间:2016-02-02 15:12:06

标签: python function recursion return global

我学习python只需要一个月左右。这是一个递归函数,我让Pygame在没有撤退的情况下在多边形中找到正确的方法。这里只是一个五角大楼,(0,1,2,3,4)是顶点的数字。

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

last_poses = {}
route_all = []

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

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

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

此结果来自返回值:

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

我的问题是在没有全局变量的情况下返回正确的值。任何可以帮助我解决这个问题的人,我真的很感激。

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

3 个答案:

答案 0 :(得分:1)

最简单的答案是使用非本地而不是全局。这是相同的交易,但变量是在父范围而不是全局范围。

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

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

This问题可能有助于您入门。

答案 1 :(得分:0)

您有几个选项。其中一个是使用可选参数。看起来您可以使用route_all作为可选参数。

e.g。

 [RegularExpression(@"^[a-zA-Z]+$&#269", ErrorMessage = "Use letters only please")]

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

另一种方法是去掉dest_all和last_poses,并且只使用一个变量route_all,并将每个到达多边形中的点附加到它,并且只返回该点。

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

您还可以考虑不使用legal_actions变量,并根据您所在的步骤编号创建“邻居”值。

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

答案 2 :(得分:0)

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

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)