【问题标题】:Is there a better way than this loopin logic?有没有比这种循环逻辑更好的方法?
【发布时间】:2019-11-06 06:17:33
【问题描述】:

我有一个带有 id 名称和标记的数组。

我想计算总分并在下一个学生进来时执行操作。

我正在使用下面的代码,但我需要在完成操作后最终调用该方法。

有没有比这更好的方法而不在循环后调用方法。



student_id_name_marks = [
    (1,"John",23),
    (2,"Paul",30),
    (2,"Paul",32),
    (2,"Paul",40),
    (3,"Doe",43),
    (3,"Doe",42),
    (4,"Jerry",45)
]


current_user_id = None
total_marks = None
for marks in student_id_name_marks:
    if current_user_id == marks[0]:
        total_marks += marks[2]
    else:
        if total_marks:
            calculate_average(total_marks)
        total_marks = marks[2]
        current_user_id = marks[0]

if total_marks:
            calculate_average(total_marks)

【问题讨论】:

  • 您的问题听起来像dictionary,键是学生姓名和值是学生获得的成绩列表,这将是更自然的数据表示。您可以选择输入格式吗?

标签: python loops stack logic


【解决方案1】:

我会将它们存储在字典中

from collections import defaultdict
marks = defaultdict(list)
for id, name, mark in student_id_name_marks:
     marks[name].append(mark)  # could use the id instead of name as key

然后你可以在之后计算每个人的平均值,这仍然是最好的方法。

for key, val in marks.items():
     calculate_average(val) # key will be the persons name if you need it

或者,考虑创建一个Person 类,其中包含标识、名称和标记列表。然后保留这些对象的列表并根据需要处理人员对象

class Person:
     def __init__(self, id, name):
          self.id = id
          self.name = name
          self.marks = []
    def add_mark(mark):
          self.marks.append(mark)
    def average_mark():
          return sum(self.marks) / len(self.marks)

【讨论】:

    【解决方案2】:

    您可以将列表转换为 pandas 数据框,以便更轻松、更快速地进行计算:

    student_id_name_marks = [
        (1,"John",23),
        (2,"Paul",30),
        (2,"Paul",32),
        (2,"Paul",40),
        (3,"Doe",43),
        (3,"Doe",42),
        (4,"Jerry",45)
    ]
    
    df= pd.DataFrame(student_id_name_marks)
    df.columns = ['id', 'Name', 'Mark']
    
       id   Name  Mark
    0   1   John    23
    1   2   Paul    30
    2   2   Paul    32
    3   2   Paul    40
    4   3    Doe    43
    5   3    Doe    42
    6   4  Jerry    45
    
    # We groupby students to get each student's average mark
    students_mean = df.groupby('id')['Mark'].mean()
    
    # We compute the average mark
    students_mean .mean()
    

    输出:

    36.125
    

    【讨论】:

      【解决方案3】:

      您可以在列表中附加一个条目并忽略它:

      student_id_name_marks = [    
          (1,"John",23),    
          (2,"Paul",30),    
          (2,"Paul",32),    
          (2,"Paul",40),    
          (3,"Doe",43),    
          (3,"Doe",42),    
          (4,"Jerry",45),    
          (-1,"EOF",0),     
      ]    
      
      current_user_id = None    
      total_marks = None        
      for marks in student_id_name_marks:    
          if current_user_id == marks[0]:    
              total_marks += marks[2]        
          else:                              
              if total_marks:                
                  print(current_user_id, total_marks)    
              total_marks = marks[2]    
              current_user_id = marks[0]
      

      生产:

      1 23
      2 102
      3 85
      4 45
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多