Rank a list of students based on marks using python list comprehension

  • Here, we are going to rank a list of students in a cleaner way without using any loops. This is achieved using python List comprehension. We have a list of students with id, name and marks in 3 different subjects.

    Normally, to rank a list, we will have to loop through the list to find the total marks of each student. Then we will have to sort and find the ranks. We can do all these in just 3 lines, if we use List comprehension. Refer sample below.

    Here we are using the python walrus operator to find the rank in the final step.
    s := s + 1

    Copied
    studentsList = [
        [1, 'Carl', 48, 47, 45 ],
        [2, 'Tim', 43, 42, 41 ],
        [3, 'Peter', 40, 44, 47 ],
        [4, 'George', 44, 49, 50 ],
        [5, 'Kim', 41, 41, 42 ]
    ]
    
    #Find Total
    listToRank = [ [ st[0], st[1], st[2]+st[3]+st[4] ]  for st in studentsList]
    #Order by using marks
    listToRank.sort(key=lambda x: x[2], reverse=True)
    #Rank
    s = 0
    rankedList = [ [ st[0], st[1], st[2], s := s + 1 ]  for st in listToRank]
    print(rankedList)
    
    Output:
    [
    	[4, 'George', 143, 1],
    	[1, 'Carl', 140, 2],
    	[3, 'Peter', 131, 3],
    	[2, 'Tim', 126, 4],
    	[5, 'Kim', 124, 5]
    ]
    
  • If input data is in key-value pairs

    The list has data in the form of key-value pairs.
    We are going to update values of the already existing key named "rank".
    This is done using a python library named operator.
    Call operator.setitem() with 3 parameters, list item, key name and the new value.

    Copied
    import operator
    
    studentsList = [
        {'id': 1, 'name': 'Carl', 'english': 48, 'science': 47, 'maths': 45, 'total': 0, 'rank': 0 },
        {'id': 2, 'name': 'Tim', 'english': 43, 'science': 42, 'maths': 41, 'total': 0, 'rank': 0 },
        {'id': 3, 'name': 'Peter', 'english': 40, 'science': 44, 'maths': 47, 'total': 0, 'rank': 0 },
        {'id': 4, 'name': 'George', 'english': 44, 'science': 49, 'maths': 50, 'total': 0, 'rank': 0 },
        {'id': 5, 'name': 'Kim', 'english': 41, 'science': 41, 'maths': 42, 'total': 0, 'rank': 0 }
    ]
    
    #Find Total
    [operator.setitem(st, "total", st["english"] + st["science"] + st["maths"]) for st in studentsList]
    
    #Order by using marks
    studentsList.sort(key=lambda x: x['total'], reverse=True)
    
    #Rank
    s = 0
    [operator.setitem(st, "rank", s := s + 1 ) for st in studentsList]
    print(studentsList)
    
    Output:
    [
    	{'id': 4, 'name': 'George', 'english': 44, 'science': 49, 'maths': 50, 'total': 143, 'rank': 1},
    	{'id': 1, 'name': 'Carl', 'english': 48, 'science': 47, 'maths': 45, 'total': 140, 'rank': 2},
    	{'id': 3, 'name': 'Peter', 'english': 40, 'science': 44, 'maths': 47, 'total': 131, 'rank': 3},
    	{'id': 2, 'name': 'Tim', 'english': 43, 'science': 42, 'maths': 41, 'total': 126, 'rank': 4},
    	{'id': 5, 'name': 'Kim', 'english': 41, 'science': 41, 'maths': 42, 'total': 124, 'rank': 5}
    ]
    
Absolute Code Works - Python Topics