递归函数调用和/或循环重复不符合预期

时间:2019-04-09 12:17:18

标签: python python-3.x

此功能应为操作列表和相应的选择列表生成是或否用户输入问题。它返回布尔值列表。 例如。 ['watch','play',...]和['footbal','sports,...] =>你看足球吗? _等。

问题:

当用户输入错误时,该函数会经常迭代-尽管您会看到这些输入是分开处理的!

我确定只有一个元素列表,此代码才能正常工作。所以这是我的代码。我知道打印调试,而且我是个流血的初学者。

def yes_or_no(action, choices, *argv):
    decisions = []
    #remember previous decisions (in case an error occured)
    for arg in argv:
        decisions = arg
    print('choices: ', choices)
    print('decisions: ', decisions)
    for choice in choices:
        print(choice)
        decision = input('Do you want to {} {}? Plase, type [y/n]: '.format(action, choice))
        try:
            decision = str(decision)
            if decision == 'y':
                decisions.append(True)
                pass
            elif decision == 'n':
                decisions.append(False)
                pass
            else:
                print('\nYour input was neither y = \'yes\' nor n = \'no\'.\nOnce again.')
                new_choices = choices[choices.index(choice):]
                yes_or_no(action, new_choices, decisions)
        except ValueError:
            print('\nYour input was neither y = \'yes\' nor n = \'no\'.\nOnce again.')
            new_choices = choices[choices.index(choice):]               
            yes_or_no(action, new_choices, decisions)
    print(decisions)
    return (decisions)

好吧,当我第一次输入无效的输入时,递归开始,但是选择中的for选择会迭代2(!)次,尽管此列表中只有一个元素!

因此,我在代码中添加了print()语句以查看它-太疯狂了!

这是我在命令行中得到的结果:

choices:  ['football', 'sports']
decisions:  []
watch
Do you want to watch football? Plase, type [y/n]: sure

Your input was neither y = 'yes' nor n = 'no'.
Once again.
choices:  ['football', 'sports']
decisions:  []
football
Do you want to watch football? Plase, type [y/n]: n
sports
Do you want to watch sports? Plase, type [y/n]: y
sports
Do you want to watch sports? Plase, type [y/n]: y
[False, True, True]

2 个答案:

答案 0 :(得分:0)

这是因为当您在choices的最后一个元素之前输入错误的decision时,会不断迭代choices。此处的解决方案应该是在调用函数后添加return语句。使用该语句更新的代码段如下所示:

def yes_or_no(action, choices, *argv):
    decisions = []
    #remember previous decisions (in case an error occured)
    for arg in argv:
        decisions = arg
    print('choices: ', choices)
    print('decisions: ', decisions)
    for choice in choices:
        print(choice)
        decision = input('Do you want to {} {}? Plase, type [y/n]: '.format(action, choice))
        try:
            decision = str(decision)
            if decision == 'y':
                decisions.append(True)
                pass
            elif decision == 'n':
                decisions.append(False)
                pass
            else:
                print('\nYour input was neither y = \'yes\' nor n = \'no\'.\nOnce again.')
                new_choices = choices[choices.index(choice):]
                return yes_or_no(action, new_choices, decisions)
        except ValueError:
            print('\nYour input was neither y = \'yes\' nor n = \'no\'.\nOnce again.')
            new_choices = choices[choices.index(choice):]               
            return yes_or_no(action, new_choices, decisions)
    print(decisions)
    return (decisions)

答案 1 :(得分:0)

你好,又是我-我只是无法使用假邮件重新登录到我快速创建的帐户:P

我在几分钟之内收到了一个有用的答案,因此,我只想与我分享此递归的最终解决方案,该递归处理由移交给该功能的两个列表生成的“是或否”问题。

def yes_or_no(action, choices, *argv):

    error_message = '\nYour input was neither y = \'yes\' nor n = \'no\'.\nOnce again.\n'
    decisions = []

    #remember previous decisions (in case an error occured)
    for arg in argv:
        decisions = arg

    for choice in choices:
        decision = input('Do you want to {} {}? Plase, type [y/n]: '.format(action, choice))

        try:
            decision = str(decision)
            if decision == 'y':
                decisions.append(True)
            elif decision == 'n':
                decisions.append(False)
            else:
                print(error_message)
                decisions = yes_or_no(action, choices[choices.index(choice):], decisions)
                break
        except ValueError:
            print(error_message)
            decisions = yes_or_no(action, choices[choices.index(choice):], decisions)
            break

    return (decisions)

简历:这种针对动机问题(“是或不是”问题处理)的解决方案可能不是最有效的解决方案,但它是全面的,可轻松应用于任何问题这类。 您可能已经意识到,我没有使用建议的“返回”,因为“中断”会产生相同的效果,因为只有一个(!)循环递归(“用于选择:”)会中断。我更喜欢'break'而不是'return',因为我认为编译器在技术上可以更快地解决它。

缺点:到目前为止,我只想到一个缺点。在有很多无效输入的情况下-很多我的意思是数百万或更多-此递归将需要越来越多的存储空间。但是我想,这是众所周知的递归。 ;-)