【问题标题】:If statement to repeat for every occurence每次出现都要重复的 if 语句
【发布时间】:2020-01-12 01:10:18
【问题描述】:

我有一个列表,其中包含不同的课程名称,后跟逗号,然后是成绩。

courses = ['COMP 1000,A+', "MATH 1000,A+", 'SCIE1000,B+"]

对于列表中出现的每次成绩,我将其更改为成绩点值并将其添加到不同的列表中。然后从那里我通过找到平均值来计算 GPA。我为此使用以下代码:

if any("A+" in n for n in courses):
    grades.append(4.30)
if any("B+" in n for n in courses):
    grades.append(3.30)

这适用于每个等级重复一次的列表,但对于上面的课程列表,有两个 A+,但 4.30 只添加一次。每次成绩在列表中时,有没有办法将 4.30 添加到新列表中?

谢谢

【问题讨论】:

    标签: python python-3.x list if-statement


    【解决方案1】:

    你做错了。循环遍历课程,以逗号分隔,并在字典中查找年级到年级的转换(相当于其他语言中的 case 语句)。

    courses = ['COMP 1000,A+', 'MATH 1000,A+', 'SCIE1000,B+']
    grades = []
    
    grade_to_grade_point = {
        "A+": 4.30,
        "B+": 3.30,
        # ...
        }
    for course in courses:
        course_name, grade = course.split(',')
        grades.append(grade_to_grade_point[grade])
    
    print(grades)  # -> [4.3, 4.3, 3.3]
    

    或者作为列表理解:

    grades = [grade_to_grade_point[c.split(',')[1]] for c in courses]
    

    【讨论】:

      【解决方案2】:

      这里有一些很好的答案,但没有一个能告诉你为什么你现在拥有的东西不起作用:

      问题在于您使用anyany 函数接受一个布尔值列表,如果列表中至少有一个值为 true,则返回 true。

      >>> any([True, True])
      True
      >>> any([True, False])
      True
      >>> any([False, False])
      False
      

      无论列表中有多少个Trues,只会返回一个布尔值,并且您的 if 语句只会运行一次。因此,即使您的列表中有两个“A+”,也只会执行一个 append

      与您尝试使用 any 函数(我能想到的)实现的最接近的事情是带有条件的列表理解:

      >>> courses = ['COMP 1000,A+', 'MATH 1000,A+', 'SCIE1000,B+']
      >>> [n for n in courses if "A+" in n]
      ['COMP 1000,A+', 'MATH 1000,A+']
      

      在这里,不满足条件"A+" in n 的项目不属于新数组。这将使您的代码如下所示:

      for i in [n for n in courses if "A+" in n]:
          grades.append(4.30)
      

      也就是说,我不建议这样做。还有其他更简洁、更易读的解决方案,例如Ismeal's solution,甚至像这样简单:

      courses = ["COMP 1000,A+", "MATH 1000,A+", "SCIE1000,B+"]
      grades= []
      for course in courses:
          if "A+" in course:
             grades.append("4.30")
      ...
      

      Bonus Pro 提示!考虑课程中可能是BIO,A+ 的可能性。这将通过 if 语句。 if "B" in course。可能值得将课程名称和成绩分开。

       >>> "Bio,A+".split(",")
       ['Bio', 'A+']
       >>> "Bio,A+".split(",")[1]
       'A+'
      

      ;) 编码愉快!

      【讨论】:

        【解决方案3】:

        使用list comprehension 怎么样?

        courses = ["COMP 1000,A+", "MATH 1000,A+", "SCIE1000,B+"]
        
        def func(x):
            if "A+" in x:
               return 4.30
            elif "B+" in x:
                return 3.30
            # add other cases
        
        grades = [func(x) for x in courses]
        
        print(grades) # [4.3, 4.3, 3.3]
        

        【讨论】:

          【解决方案4】:

          如果你想在一行中使用它:

          courses = ['COMP 1000,A+', "MATH 1000,A+", "SCIE1000,B+"]
          points = {'A+': 4.30, 'B+': 3.30}
          grades = [value for grade, value in points.items() for course in courses if grade in course]
          print(grades)
          
          >>> [4.3, 4.3, 3.3]
          

          【讨论】:

            【解决方案5】:

            现有的答案很好,但我想展示一种更面向对象的方法,以防万一。就我个人而言,我更喜欢函数式风格,但 OO 是现在所教授的大部分内容。

            from decimal import Decimal  # for precise decimals instead of float math
            
            class Course:
                def __init__(self, name, lettergrade):
                    self.name = name
                    self.lettergrade = lettergrade
            
                @classmethod
                def from_string(cls, s):
                    name, lettergrade = s.split(',')
                    return cls(name.strip(), lettergrade.strip())
            
                @property
                def gradepoint(self):
                    mapping = {
                        "A+": Decimal('4.3'),
                        "A": Decimal('4'),
                        "A-": Decimal('3.7'),
                        "B+": Decimal('3.3'),
                        "B": Decimal('3'),
                        ... # etc
                    }
            
                    return mapping.get(self.lettergrade)
            
            # Read the input into `courses`, then:
            
            courses = [Course.from_string(c) for c in courses]
            grades = [c.gradepoint for c in courses]
            
            from statistics import mean
            
            avg = mean(grades)  # gives a Decimal equal to your mean grade
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-08-05
              • 2013-08-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-12-04
              • 2021-07-19
              相关资源
              最近更新 更多