문제
도현이네 반 학생 N명의 이름과 국어, 영어, 수학 점수가 주어진다. 이때, 다음과 같은 조건으로 학생의 성적을 정렬하는 프로그램을 작성하시오.
- 국어 점수가 감소하는 순서로
- 국어 점수가 같으면 영어 점수가 증가하는 순서로
- 국어 점수와 영어 점수가 같으면 수학 점수가 감소하는 순서로
- 모든 점수가 같으면 이름이 사전 순으로 증가하는 순서로 (단, 아스키 코드에서 대문자는 소문자보다 작으므로 사전순으로 앞에 온다.)
- 입력
첫째 줄에 도현이네 반의 학생의 수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 100보다 작거나 같은 자연수이다. 이름은 알파벳 대소문자로 이루어진 문자열이고, 길이는 10자리를 넘지 않는다.
- 출력
문제에 나와있는 정렬 기준으로 정렬한 후 첫째 줄부터 N개의 줄에 걸쳐 각 학생의 이름을 출력한다.
lambda 함수
이 문제를 풀기 위해서는 lambda 함수
라는 것을 알아야 한다.
람다 함수는 이름 없이 간단히 사용할 수 있는 함수다. 실제 함수와 비교하면 아래와 같다.
#일반 함수
def func(x, y):
return x+y
#람다 함수
lambda x,y : x+y
좀 더 복잡하게 map
함수 안에서 람다를 사용할 수도 있다.
print(map(lambda x : x*x, [1, 2, 3, 4, 5]))
#출력: [1, 4, 9, 16, 25]
print(map(lambda x, y : x+x, [1, 2, 3, 4, 5], [6,7,8,9,10]))
#출력: [7, 9, 11, 13, 15]
print(map(lambda x : x*2 if x % 2 == 0 else 0, [1,2,3,4,5,6,7,8,9,10]))
#출력: [0, 4, 0, 8, 0, 12, 0, 16, 0, 20]
이번 문제에서는 sort 함수 내에서 정렬의 기준이 되는 key 값을 람다 함수를 통해 정해준다. 코드는 아래에서 확인할 수 있다..
람다 함수에 대한 더 자세한 내용은 여기를 참고하자!
최종 코드
위에서 설명한 람다 함수를 사용한 코드는 아래와 같다. 조건 4순위부터 1순위 순서로 코딩해서 조건을 만족했다.
import sys
n = int(sys.stdin.readline())
arr = []
for i in range(n):
name, kor, eng, math = sys.stdin.readline().split()
arr.append([name, int(kor), int(eng), int(math)])
arr.sort(key = lambda array: array[0])
arr.sort(key = lambda array: array[3], reverse = True)
arr.sort(key = lambda array: array[2])
arr.sort(key = lambda array: array[1], reverse = True)
for student in arr:
print(student[0])
Enhanced
위에서는 sort 함수를 4번이나 불렀는데, sort 한 번으로 더 간단하게 해결하는 방법도 있었다.
import sys
n = int(sys.stdin.readline())
arr = []
for i in range(n):
name, kor, eng, math = sys.stdin.readline().split()
arr.append([name, int(kor), int(eng), int(math)])
arr.sort(key = lambda array: -array[1], array[2], -array[3], array[0])
for student in arr:
print(student[0])
참고 사이트
- 파이썬 람다(lambda) 함수 thrillfighter.tistory.com/356
- 백준(boj) 10825 파이썬 - 국영수 infinitt.tistory.com/135