简体   繁体   English

如何在python中使用递归

[英]How to use recursion in python

I am trying to solve a problem which stimulate movements of a robot. 我试图解决刺激机器人运动的问题。 The robot starts with position (0, 0, 'N'). 机器人从位置(0,0,'N')开始。 The command is given in a list of strings. 该命令在字符串列表中给出。 the 'turn' function turns from N to E to S to W and back to N. The move function moves in the specific direction: N,S in y axis and E,W in x axis. 'turn'功能从N变为E,S变为W并返回N.移动功能沿特定方向移动:Y轴为N,S轴为E轴,E为W轴。 N: y+1 S: y-1 W: x-1 E: x+1 N:y + 1 S:y-1 W:x-1 E:x + 1

The part I am having trouble with is, when trying to use shortcuts in the function. 我遇到问题的部分是,当试图在函数中使用快捷方式时。 Using 'turnleft' instead of ['turn', 'turn', 'turn'], 'turnright' instead of 'turn' 使用'turnleft'代替['turn','turn','turn'],'turnright'而不是'turn'

def macro_interpreter(code, macros):

when call the function: 调用函数时:

print(macro_interpreter(['turnleft', 'turnright'], {'turnleft': ['turn', 'turn', 'turn'], 'turnright' : ['turn'], 'bigleftturn' : ['move', 'move', 'turnleft', 'move', 'move'], 'bigrightturn' : ['move', 'move', 'turnright', 'move', 'move']}))

the definition of the term is given in a dictionary. 该术语的定义在字典中给出。 My code only runs for the first command and then terminate, it ignores the second code in the list 我的代码只运行第一个命令,然后终止,它忽略列表中的第二个代码

def macro_interpreter(code, macros):
    x,y,index = 0, 0, 0
    state = ['N', 'E', 'S', 'W']
    for command in code:
        if command in macros:
            return macro_interpreter(macros[command], macros)
        else:
            if command == 'move':
                if state[index] == 'N':
                    y += 1
                elif state[index] == 'E':
                    x += 1
                elif state[index] == 'S':
                    y -= 1
                elif state[index] == 'W':
                    x -= 1
            elif command == 'turn':
                try:
                    index = index + 1
                except IndexError:
                    index = 0
    return (x, y, state[index])            

If you always hit the one else statement in the loop over the code commands, then you never will recurse because command not in macros . 如果你总是通过code命令在循环中点击一个else语句,那么你永远不会递归,因为command not in macros

After the first iteration, code == ['turn', 'turn', 'turn'] , but macros contains no key "turn" 在第一次迭代之后, code == ['turn', 'turn', 'turn'] ,但macros包含键"turn"


If you wish to do this more correctly, then you can pass along x, y, and the "direction index state" as parameters to the function, then increment / modify those within the recursive call rather than only modify local variables of the function and always restart them back at (0,0, 0). 如果您希望更正确地执行此操作,那么您可以将x,y和“方向索引状态”作为参数传递给函数,然后在递归调用中递增/修改它们,而不是仅修改函数的局部变量和总是重新启动它们(0,0,0)。

Also, you need to replace that try except with index = (index + 1) % len(state) because no IndexError is going to be caught by incrementing a number 此外,您需要替换该尝试,除非使用index = (index + 1) % len(state)因为不会通过递增数字来捕获IndexError


So, something like this 所以,这样的事情

state = ['N', 'E', 'S', 'W']
def macro_interpreter(code, macros, x=0,y=0,index=0):
    # TODO: check if x or y have gone outside "the board" 
        # TODO: return to break from recursion 

    for command in code:
        if command in macros:
            return macro_interpreter(macros[command], macros,x,y,index)
        else:
            if command == 'move':
                if state[index] == 'N':
                    return macro_interpreter(code[1:], macros,x,y=y+1,index)

There are some amendments which i did in your code to support recursion properly. 我在您的代码中做了一些修改以正确支持递归。 This code will do, what you want to acheive. 这段代码会做什么,你想要实现什么。

def macro_interpreter(code, macros, x=0, y=0, index=0):
    state = ['N', 'E', 'S', 'W']
    for command in code:
        if command in macros:
            x, y, curr_state = macro_interpreter(macros[command], macros, x, y, index)   
            # update new index with new state value         
            index = state.index(curr_state)
        else:
            if command == 'move':
                if state[index] == 'N':
                    y += 1
                elif state[index] == 'E':
                    x += 1
                elif state[index] == 'S':
                    y -= 1
                elif state[index] == 'W':
                    x -= 1
            elif command == 'turn':                
                index = (index + 1)%len(state)
    return (x, y, state[index])   

Now, if i run your test case 现在,如果我运行你的测试用例

>> print macro_interpreter(['turnleft', 'turnright'], {'turnleft': ['turn', 'turn', 'turn'], 'turnright' : ['turn'], 'bigleftturn' : ['move', 'move', 'turnleft', 'move', 'move'], 'bigrightturn' : ['move', 'move', 'turnright', 'move', 'move']})
 Output:- (0, 0, 'N')

I hope this will helps you. 我希望这会对你有所帮助。

The line 这条线

return macro_interpreter (macros etc.

will do just that. 会这样做的。 It will leave the for loop and return from the outer call. 它将离开for循环并从外部调用返回。 End of story. 故事结局。

I suspect it's because you return 我怀疑是因为你回来了

macro_interpreter(macros[command], macros)

This simply exits the function once the recursed code is run. 一旦运行递归代码,这只会退出函数。 You'll see if you change 你会看到你是否改变了

return macro_interpreter(macros[command], macros)

to

print macro_interpreter(macros[command], macros)

that the code will print what you want it to do. 代码将打印您想要它做的事情。 How you want to actually handle the output is up to you. 您希望如何实际处理输出取决于您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM