# Nested Lists from HackerRank

I am a beginner in python. This is the Nested Lists problem from HaackerRank.

Given the names and grades for each student in a Physics class of N students, store them in a nested list and print the name(s) of any student(s) having the second lowest grade.

Note: If there are multiple students with the same grade, order their names alphabetically and print each name on a new line.

I want to improve my code with better functions available in python and I want to decrease lines of code.

if __name__ == '__main__':
scorecard = []
for _ in range(int(input())):
name = input()
score = float(input())
scorecard.append([name, score])
scorecard.sort(key = lambda x:x)
names = []
lowest_score = scorecard
second_lowest = 0
for i in range(len(scorecard)):
if scorecard[i] > lowest_score and second_lowest == 0:
second_lowest = scorecard[i]

if second_lowest != 0 and scorecard[i] == second_lowest:
names.append(scorecard[i])

names.sort()

for name in names:
print(name)


1. I'd recommend separating the logic of getting the user input from the logic of building and sorting the nested list.
2. Your code doesn't build a nested list in a way that's useful for solving the problem; I think what you want is a list of lists of names, where each list of names corresponds to a grade.
3. Any time you want to group things into buckets (e.g. all the names that go with a grade), it's a good time to use a dictionary!
4. Using list comprehensions is frequently a good way to express a loop in a shorter way.
5. Type annotations make it easier to keep track of what your code is doing (and they let you use mypy to catch bugs).

Here's my solution that uses a separate function to build the nested list, using a dictionary as an intermediate step to collect all the names for a given grade. Note that the type annotations tell you exactly where the names (strings) and grades (floats) are going at each step!

from collections import defaultdict
from typing import Dict, List, Tuple

"""
Given a list of (name, grade) tuples, return a list of names for each grade.
Each list is sorted, i.e.:
the top level list is sorted from lowest to highest grade
each list of names is sorted alphabetically
"""

• 2 small improvements: your function can accept any finite Iterable[Tuple[str, float]], not just lists, and [sorted(names) for _, names in sorted(grade_list.items())] expresses the final result clearer in my opinion. Mar 30 '20 at 16:34