【问题标题】:How do you structure a recursive function?你如何构造一个递归函数?
【发布时间】:2015-10-07 19:53:47
【问题描述】:

我正在尝试创建一个递归函数来检查成绩是否可以转换为浮点数,然后检查以确保成绩在 0 到 100 之间。我关于为什么会这样的逻辑是:

  1. 检查成绩是否可以转换为浮点数。
  2. 如果不能转换成浮点数,用户会收到错误信息,必须输入新的成绩,gradeChecker 会再次检查。
  3. 如果可以转换为浮点数,gradeChecker 会检查它是否在 0 到 100 之间
  4. 如果成绩介于 0 和 100 之间,则该成绩将附加到“作业”字典中。
  5. 如果分数不在 0 到 100 之间,用户会给出一个新分数,并将其传回函数,因此从第 1 步开始重复。

你能告诉我这段代码怎么不符合那个逻辑吗?

def gradeChecker(grade):
    while True:
        try:
            grade = float(grade)        
            while (grade < 0) or (grade > 100):
                print("Sorry, your grade must be between 0 and 100.")
                grade = input("What grade did you receive on: %s? " % assignment)
                gradeChecker(grade)
        except:
            print("Sorry, that's an invalid input. Please only use numbers and decimal points!")
            grade = input("What grade did you receive on: %s? " % assignment)
        else:
            break
    Assignments[assignment].append(grade)

编辑:缩进已修复!

作为参考,这里是我用来将成绩传递到gradeChecker 的全部代码。

import collections #We import collections so we can use an ordered dictionary
Assignments = collections.OrderedDict() #We create an ordered dictionary called 'Assignments'
#We have to add each assignment to our dictionary individually because it's an ordered dictionary
#You can't convert a regular dictionary, which is unordered, to an ordered dictionary
#If you used a regular dictionary, when looping through the assignments they would be displayed at random
Assignments['Exam 1'] = [0.2] #We add the assignment and the weight to the dictionary
Assignments['Exam 2'] = [0.2] #We add the assignment and the weight to the dictionary
Assignments['Exam 3'] = [0.2] #We add the assignment and the weight to the dictionary
Assignments['Homework'] = [0.2] #We add the assignment and the weight to the dictionary
Assignments['LQR'] = [0.1] #We add the assignment and the weight to the dictionary
Assignments['Final'] = [0.1] #We add the assignment and the weight to the dictionary

#We have to define our grade checker before it is called so that it can be used to verify users inputs

def gradeChecker(grade): #Used to verify that a users grades are in-between 0 and 100
    while True:
        try:
            grade = float(grade)        
            while (grade < 0) or (grade > 100):
                print("Sorry, your grade must be between 0 and 100.")
                grade = input("What grade did you receive on: %s? " % assignment)
                gradeChecker(grade)
        except:
            print("Sorry, that's an invalid input. Please only use numbers and decimal points!")
            grade = input("What grade did you receive on: %s? " % assignment)
        else:
            break
    Assignments[assignment].append(grade) #We append the grade to the assignment to be used with it's weight for the final grade calculation

#INPUT

for assignment in Assignments.keys(): #We loop through every assignment in our  Assignments dictionary
    grade = input("What grade did you receive on: %s? " % assignment) #We ask the user to enter their grade
    gradeChecker(grade) #We check to see if their grade is valid by passing their input through the gradeChecker function

【问题讨论】:

  • 你应该检查你的缩进。究竟什么是作业?
  • 每个等级,无论是否有效,都将附加到列表中,我认为这不是您的意图
  • 并且由于每次调用内部的成绩都不会改变,因此如果用户输入错误,您的 while 循环将永远不会中断。我建议退出 while 循环(因为无论如何你都在进行递归调用)并将 append 放在你的 else 块中
  • 如果您不愿意花时间在问题中找到正确的缩进,我们为什么要花时间回答问题?缩进是 Python 语法的关键部分。
  • @Alex,我在问题中添加了更多上下文!

标签: python function python-3.x recursion python-3.4


【解决方案1】:

在这里同时使用递归和循环是多余的。此外,循环应该优先于 Python 等“普通”语言(即不是 Lisp)中的递归,除非您正在处理像树这样的固有递归数据结构。

鉴于你从来没有说过为什么你首先需要使用递归,我建议使用这样的东西:

def input_grade(assignment):
    while True:
        try:
            grade = input("What grade did you receive on: %s? " % assignment)
            grade = float(grade)
            if grade < 0 or grade > 1000:
                raise ValueError
            return grade
        except:
            print("Sorry, that's an invalid input. Please only use numbers and decimal points!")

for assignment in Assignments:
    Assignments[assignment].append(input_grade(assignment))

注意 1。我没有测试上面的代码,但它应该能让你大致了解如何构造这个函数。

注意 2。你应该避免在函数中修改Assignments,这是一个不需要的副作用。最好将其卸载到主代码中。

注 3。从技术上讲,我的代码中的 try..except 是基于异常的逻辑的示例,这不是一件好事(但是,这比在这里使用递归要好得多)。

【讨论】:

    【解决方案2】:
    def gradeChecker(grade):
        try:
            grade = float(grade)        
            while (grade < 0) or (grade > 100):
                print("Sorry, your grade must be between 0 and 100.")
                grade = input("What grade did you receive on: %s? " % assignment)
                gradeChecker(grade)
        except:
            print("Sorry, that's an invalid input. Please only use numbers and decimal points!")
            grade = input("What grade did you receive on: %s? " % assignment)
        else:
            Assignments[assignment].append(grade)
    

    您的代码的问题是它是多余的; while 语句可以做你已经有递归调用做的事情。 imo,while 语句更好,因为递归通常会占用更多内存,但这只是一种意见。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 1970-01-01
      • 2014-07-08
      • 2014-01-19
      • 1970-01-01
      • 2016-06-04
      • 2013-11-29
      相关资源
      最近更新 更多