중첩 리스트에 학생들의 이름과 성적이 저장되어 있을 때, 두 번째로 낮은 점수를 받은 학생의 이름을 모두 출력하는 문제를 생각해 봅시다. 만약 두 번째로 낮은 점수를 받은 학생이 여러 명이라면, 이름을 알파벳 순으로 정렬한 뒤 한 줄에 하나씩 출력해야 합니다.
문제 이해
예를 들어 입력이 다음과 같다고 가정해 보겠습니다.
students = [['Amal',37],['Bimal',37],['Tarun',36],['Akash',41],['Himadri',39]]
이 경우 최저 점수는 Tarun의 36점이고, 두 번째로 낮은 점수는 Amal과 Bimal의 37점입니다. 따라서 출력 결과는 두 이름이 알파벳 순으로 정렬되어 다음과 같아야 합니다.
Amal Bimal
해결 접근 방법
이 문제는 다음 단계를 통해 해결할 수 있습니다.
- 전체 학생 중 가장 낮은 점수(min_mark)를 구합니다.
- 최저 점수보다 점수가 높은 학생들만 남긴 새로운 리스트를 만듭니다. 이렇게 하면 최저 점수를 받은 학생이 제외됩니다.
- 남은 학생들 중 다시 가장 낮은 점수(min2_mark)를 구합니다. 이것이 곧 '두 번째로 낮은 점수'입니다.
- min2_mark와 같은 점수를 받은 학생들의 이름만 추출한 뒤, sorted() 함수로 알파벳 순으로 정렬합니다.
- 정렬된 이름 목록을 한 줄씩 출력합니다.
구현 예제
위 로직을 파이썬 코드로 구현하면 다음과 같습니다.
def solve(students):
min_mark = min(x[1] for x in students)
students = [x for x in students if x[1] > min_mark]
min2_mark = min(x[1] for x in students)
students = sorted([x[0] for x in students if x[1] == min2_mark])
for x in students:
print(x)
students = [['Amal',37],['Bimal',37],['Tarun',36],['Akash',41],['Himadri',39]]
solve(students)입력
[['Amal',37],['Bimal',37],['Tarun',36],['Akash',41],['Himadri',39]]
출력
Amal Bimal
코드 설명
첫 번째 줄의 min() 함수는 제너레이터 표현식을 사용해 모든 학생의 점수(x[1]) 중 최솟값을 찾습니다. 그다음 리스트 컴프리헨션으로 최저 점수를 받은 학생을 제외한 새 리스트를 생성합니다. 여기서 다시 최솟값을 구하면 자연스럽게 두 번째로 낮은 점수를 얻게 됩니다. 마지막으로 해당 점수를 받은 학생들의 이름만 골라 sorted()로 정렬하고 반복문으로 출력하면 원하는 결과를 얻을 수 있습니다.
이 방법의 시간 복잡도는 O(n)으로, 학생 수가 많아도 효율적으로 동작한다는 장점이 있습니다.