替换字典中元组列表中元组的单个元素

问题描述 投票:0回答:1

我有一本字典作为学生数据库。每个键都是一个学生姓名,每个键的值是由课程名称和成绩组成的元组列表。一个学生可以有很多门课程。

问题 1:我知道元组是不可变的,因此我需要一种解决方法来替换特定课程的成绩值。

问题2:学生可以重修课程,如果成绩高于最初的成绩,则成绩会更新。如果较低,则不更新等级。成绩为 0 的课程不包括在内。

我似乎不能排除添加现有的较低年级课程。我不断收到“编程入门”课程的重复内容,并添加了较低年级的“2”。

我已经盯着这个几乎一天了,任何帮助将不胜感激。如果阅读和解释这本书很痛苦,我很抱歉。我对编程还很陌生。

def add_student(students: dict, name: str): 
    if len(students) == 0:
        students[name] = [()]

    if name not in students:
        students[name] = [()]
    return students

def print_student(students: dict, name: str):
    if name not in students:
        print(f"{name}: no such person in the database")
    elif students[name] == [()]:
        print(f"{name}:\n no completed courses")
        
    else:
        print(f"{name}:\n {len(students[name])} completed courses:")
        for i in range(len(students[name])):
            print(f"  {students[name][i][0]} {students[name][i][1]}")
        
        sum_course = 0
        for i in range(len(students[name])):    
            sum_course += students[name][i][1]
        print(f" average grade: {sum_course / len(students[name])}")
    return

def add_course(students: dict, name: str, course: tuple):
    if name not in students:
        print(f"{name}: no such person in the database")
        
    elif students[name] == [()] and course[1] != 0:
        students[name].append(course)
        students[name].remove(())
    
    elif course[0] not in students and course[1] !=0:
        students[name].append(course)
    
    return students
        
    
if __name__ == "__main__":
    students = {}
    add_student(students, "Peter")
    print()
    
    add_course(students, "Peter", ("Introduction to Programming", 3))
    add_course(students, "Peter", ("Advanced Course in Programming", 2))
    add_course(students, "Peter", ("Data Structures and Algorithms", 0))
    add_course(students, "Peter", ("Introduction to Programming", 2))
    print()

    print(students)
    print()
    print_student(students, "Peter")
python python-3.x dictionary indexing tuples
1个回答
0
投票

我采纳了 @ShadowRanger 的建议,并将其放入完整的答案中,并附有代码和大量注释来解释正在发生的事情。

这是高级注释

  • 您可以将学生更改为
    dict
    ,键为学生姓名,键为
    dict
    ,键为课程名称和成绩值。这使得访问、更新等变得更加容易
  • 因为我们没有使用错误来指示函数中发生了什么,所以您可以使用
    add_student
    add_course
    print_student
    中的返回值来指示是否执行了任何操作
    • 您不需要再次返回
      dict
      ,因为它已被函数更改了
  • 您可以重构
    add_student
    使其更清晰一些 - 检查可迭代对象是否为空,然后检查某个项目是否在该可迭代对象中是多余的,Python 可以优雅地处理
    in
    对空可迭代对象的调用
  • 您可以从
    add_course
    返回工作,与
    add_student
  • 一样
  • 您可以稍微重组 print Student 以反映新数据结构的好处
  • 您可以在
    add_course
    上指示元组内的类型,因为该功能非常严格

这里有一些代码演示了这些建议:

def add_student(students: dict, name: str) -> bool:
    # If this student is already in the students, no operation
    #   return False to indicate no changes
    if name in students:
        return False
    # If this is a new student, put in a dict for them
    #   return True to indicate a change
    students[name] = {}
    return True


def add_course(students: dict, name: str, course: tuple[str, int]) -> bool:
    # If the student isn't in students, print the warning and
    #   return False to indicate no changes
    if name not in students:
        print(f'{name}: no such person in the database')
        # We could optionally instead throw an error here and
        #   let the calling function handle it
        return False
    # If the student got a 0, ignore the request and
    #   return False to indicate no changes
    if course[1] == 0:
        # We don't include courses with 0 grade
        return False
    # If this is the first time they took the course, add it and
    #   return True to indicate an update
    if course[0] not in students[name]:
        students[name][course[0]] = course[1]
        return True
    # If the student took it before and did better this time, update it and
    #   return True to indicate an update
    if course[1] > students[name][course[0]]:
        students[name][course[0]] = course[1]
        return True
    # If the student took it before and id better then, leave it and
    #   return False to indicate no changes
    return False


def print_student(students: dict, name: str) -> bool:
    # If the student isn't in students, print the warning and
    #   return False to indicate the student print failed
    if name not in students:
        print(f'{name}: no such person in the database')
        # We could optionally instead throw an error here and
        #   let the calling function handle it
        return False
    # Print the student name and course count
    print(f'{name}:')
    # Print the number of completed courses
    #   If only 1 has been completed, no 's' should be added to 'course'
    #   i.e., no courses, 1 course, 2 courses, 3 courses, etc
    print(f' {len(students[name]) or "no"} completed course' +
        ('' if len(students[name]) == 1 else 's')
    )
    # This loop will print each course, if there are any
    for course, grade in students[name].items():
        print(f'  {course} {grade}')
    # This will print the average grade if the student has taken 1 or more
    if len(students[name]):
        print(f' average grade: {sum(students[name].values()) / len(students[name])}')
    # return True to indicate the student print succeeded
    return True


if __name__ == "__main__":
    students = {}
    add_student(students, "Peter")
    add_student(students, "Sally")
    print()

    add_course(students, "Peter", ("Introduction to Programming", 3))
    add_course(students, "Peter", ("Advanced Course in Programming", 2))
    add_course(students, "Peter", ("Data Structures and Algorithms", 0))
    add_course(students, "Peter", ("Introduction to Programming", 2))
    print()

    print(students)
    print()
    print_student(students, "Peter")
    print_student(students, "Sally")

© www.soinside.com 2019 - 2024. All rights reserved.