有没有比这种循环逻辑更好的方法?

时间:2019-06-24 12:27:01

标签: python loops stack logic

我有一个带有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)

3 个答案:

答案 0 :(得分:2)

我会将它们存储在字典中

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类,其中包含ID,名称和标记列表。然后保留这些对象的列表,并根据需要处理人员对象

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)

答案 1 :(得分:2)

您可以将列表转换为熊猫数据框,以实现更轻松,更快速的计算:

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

答案 2 :(得分:0)

您可以将条目添加到列表中,然后忽略它:

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