【问题标题】:Loops in Python: not expecting this outputPython中的循环:不期望这个输出
【发布时间】:2021-09-26 13:51:10
【问题描述】:

我不明白为什么在循环列表时只返回一个值。

def calculateGrade(students_marks):
    # Write your code here
    
    students_avg = []
    for j in students_marks:
        sume = 0
        for i in j:
            sume = sume+ i
        avg = sume/(len(j))
        students_avg.append(avg)
    print(students_avg)

    grade = []
    for item in students_avg:
        if item >= 90:
            grade.append('A+')
        elif 80<item<=90 :
            grade.append('A')
        elif 70<item<=80 :
            grade.append('B')
        elif 60<item<=70 :
            grade.append('C')
        elif 50<item<=60:
            grade.append('D')
        elif item < 50 :
            grade.append('F')
    print(grade)
        

我尝试使用 [50.6,48] 列表中的 2 个元素,它只返回 F

这是我要执行的代码。我将 student_avg 作为正确的输出。但是当我通过第二个 for 循环传递该列表时,我只得到单个输出

第 1 行 = [66, 61, 88, 26, 13] -- 学生 1 第 2 行 = [52, 38, 7, 74, 62] -- 学生 2

所以我们形成一个学生的平均成绩列表并通过它来获得成绩。这就是问题所在。

【问题讨论】:

  • for you 之后需要缩进
  • 那是在我的 jupyter notebook 中缩进的。这是我第一次发布问题所以有一些问题
  • 您正在检查 range(x,y) 中是否存在浮点数。 range(x,y) 仅包含 xy 之间的整数。
  • @AmirrezaRiahi 那么我们应该如何检查。我们需要在浮点类型中比较它们吗?
  • @ChaitanyaSai 使用 &gt;&lt;= ,我已经回答了下面的详细说明。

标签: python python-3.x loops


【解决方案1】:

您需要缩进您的代码。而且,每次运行循环时,您都会创建一个空数组。 这样做:

grade = []
for item in students_avg:
    if item >= 90:
        grade.append('A+')
    elif item in range(80,90):
        grade.append('A')
    elif item in range(70,80):
        grade.append('B')
    elif item in range(60,70):
        grade.append('C')
    elif item in range(50,60):
        grade.append('D')
    elif item < 50 :
        grade.append('F')
print(grade)

【讨论】:

    【解决方案2】:

    每次通过 students_avg 时,您都会创建空的 grade 列表,这就是为什么您只会得到一个结果。

    就这样吧:

    def calculateGrade(
            students_marks
            ):
        # Write your code here
    
        students_avg = []
        for j in students_marks:
            sume = 0
            for i in j:
                sume = sume + i
            avg = sume / (len(j))
            students_avg.append(avg)
        print(students_avg)
    
        grade = []
        for item in students_avg:
            if item >= 90:
                grade.append('A+')
            elif 80 <= item < 90:
                grade.append('A')
            elif 70 <= item < 80:
                grade.append('B')
            elif 60 <= item < 70:
                grade.append('C')
            elif 50 <= item < 60:
                grade.append('D')
            elif item < 50:
                grade.append('F')
        return grade
    
    
    print(calculateGrade([[90,89.9], [90,90]]))
    
    Prints:
    # [89.95, 90.0]
    # ['A', 'A+']
    
    

    或者更优雅的解决方案

    rating = {
        'A+': [90, 100],
        'A': [80, 90],
        'B': [70, 80],
        'C': [60, 70],
        'D': [50, 60],
        'F': [0, 50]}
    
    
    def calculate_averages(
            students_marks
    ):
        students_avg = [sum(student) / len(student) for student in students_marks]
        return students_avg
    
    
    def get_grade(
            averages
    ):
        grades = []
        for item in averages:
            for k, v in rating.items():
                if v[0] <= item < v[1]:
                    grades.append(k)
        return grades
    
    
    if __name__ == "__main__":
        points = [[90, 89.9], [90, 90]]
        print(get_grade(calculate_averages(points))) # Prints ['A', 'A+']
    
    
    

    【讨论】:

    • 单独运行时,我得到了正确的结果。我尝试将此添加到另一个代码块中,它再次返回单个输出
    • @ChaitanyaSai 它实际上也取决于其他代码。但是请检查用户的答案。 *.com/a/69335707/10306224,bcs 这不太明显,他是对的。您可以编辑您的帖子,以便我们查看。
    • 更新了整个代码,请检查一次
    • 你有students_marks的例子,所以我们可以使用相同的输入吗? :)
    • 我当然也会这样
    【解决方案3】:

    您的成绩是float,您不能使用如下范围:

    >>> 50.6 in range(50,60)
    False
    

    如果你想使用你的代码,你可以像下面这样使用round():

    >>> round(50.6) in range(50,60)
    True
    

    或者你可以试试这个:

    dct_rng = {'A+':[90,100], 'A':[80,90], 'B' :[70,80], 
               'C':[60,70], 'D':[50,60], 'F':[0,50]}
    
    grade = []
    students_avg = [50.6 ,48]
    
    for item in students_avg:
        for k,v in dct_rng.items():
            if v[0] < item <= v[1]:
                grade.append(k)
    

    输出:

    ['D', 'F']
    

    【讨论】:

    • 观察力也不错。
    • @user1740577 这需要额外的空间来创建字典,并且代码复杂度更高。当我们可以直接与等量代码进行比较时,为什么会有额外的开销?尽管为此探索round() 确实是一个不错的选择。
    • @Zenquiorra 首先非常感谢,然后我说:我不同意你的观点,这有助于提高可读性,我们可以只用一个 dictionary 逃离 if .. elif... elif ... elif ... else。第三:这是一种解决方案。 OP 和其他用户可以阅读所有解决方案并决定哪种方案更适合他们。
    • @user1740577 我同意对于某些人来说它可能更具可读性,但这取决于个人喜好,尽管以通过放置单个值手动定义字典为代价转义 if ...elif... 可能不是当我们必须编写等效长度、非常复杂、额外空间代码和更高开销时,这是一个很好的权衡(对于更大的字典,这种方法变得非常可行)。当然,OP 可以决定什么对他们最有利,而不是我问为什么要选择这个而不是更简单的方法。可读性确实很重要。谢谢
    • @Guimute 对于大量的成绩,当然,正如我在上面的评论中所说的那样,它变得非常可行。相反,我要求的是这个特殊情况。另外,如何通过定义字典来减少追加?
    【解决方案4】:

    您的代码需要缩进,并且如果您在 for 循环之外定义的 item 小于 50,那么它正在执行最后一个条件。

    如果您的代码确实正确缩进并且您在此处粘贴代码时出错,即使如此,您的列表 grade 也需要在循环之外定义,因为它会在每次迭代时重新分配给 grade = [],并且它在前一次迭代中的任何值都消失了。

    此外,您需要非整数值,range() 将产生范围内的整数,因此 range(m,n) 将具有整数:m , m + 1,... n-1

    所以任何浮点数,例如:m.x 不会在range(m,n) 中生成,为了进行比较,最好有&gt;&lt;。同样使用range() 也不是最佳选择,因为它会占用额外的空间。

    
    grade = [] 
    for item in student_avg:
        if item >= 90:
            grade.append('A+')
        elif 90 < item <= 80:
            grade.append('A')
        elif 80 < item <= 70:
            grade.append('B')
        elif 70 < item <= 60:
            grade.append('C')
        elif 60 < item <= 50:
            grade.append('D')
        elif item < 50 :
            grade.append('F')
    
    print (grade)
    

    【讨论】:

    • @don'ttalkjustcode 哦,问题现在已编辑。早些时候它有不同的问题,并没有提到非整数值。我已经修改了答案。