https://school.programmers.co.kr/learn/courses/30/lessons/42579?language=python3
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
내 코드
def solution(genres, plays):
answer = []
mlist = {}
total_score={}
for idx, (genre, play) in enumerate(zip(genres, plays)):
if genre in mlist:
mlist[genre].append((idx, play))
total_score[genre] += play
else:
mlist[genre] = [(idx, play)]
total_score[genre] = play
mlist = sorted(mlist.items(), key=lambda x: total_score[x[0]], reverse=True)
for genre, info in mlist: #장르, 노래정보
for idx, play in sorted(info, key= lambda x: x[1], reverse=True)[:2]:
answer.append(idx)
return answer
코드 리뷰
dictionary, lambda 정렬
이 문제는 프로그래머스의 해시 카테고리 안에 있는 문제인데, 해시 카테고리가 없더라도 무조건 dict가 편할 것 같다는 느낌이 오는 문제이다. 문제를 풀기 위해 lambda로 푸는 방식을 계속 생각했는데, 역시 lambda로 해결하는 게 정말 편했다.
이 문제에서는 두 개의 list가 주어진다. 하나는 노래 장르, 하나는 플레이한 횟수가 담겨있는 리스트이다. 이를 다음의 조건에 따라 정렬해서 출력해야 한다.
- 플레이 횟수가 가장 많은 장르 순서
- 그 안에서도 플레이 횟수가 많은 idx 순서
- 각 장르별 2개씩 출력
answer = []
mlist = {}
total_score={}
for idx, (genre, play) in enumerate(zip(genres, plays)):
if genre in mlist:
mlist[genre].append((idx, play))
total_score[genre] += play
else:
mlist[genre] = [(idx, play)]
total_score[genre] = play
나는 우선 두 개의 dict를 사용했다. 하나는 mlist로, 각각의 장르별 플레이 횟수와 idx를 저장하는 리스트이다. 다른 하나는 total_score로 장르별 전체 플레이 횟수를 저장하는 dict이다.
그리고 idx를 생각하기 위해 enumerate와 zip을 사용했다. 먼저 장르별 순위를 매기기 위해 zip(장르, 플레이 횟수)를 묶어주었고, mlist에 저장했다. 그리고 동시에 total_score에 해당하는 장르의 플레이 횟수를 누적해서 더했다. 이러면 기본 세팅은 끝난다.
mlist = sorted(mlist.items(), key=lambda x: total_score[x[0]], reverse=True)
그리고 mlist를 정렬해준다. 이를 정렬하는 이유는 첫 번째 조건인 장르의 전체 플레이 횟수가 높은 순대로 정렬한다는 조건 때문이다. 그래서 mlist.items()로 key와 value를 불러준다.
그리고 첫 번째는 total_score[x[0]] 순으로 정렬, 두 번째로 x[1]이 높은 순대로 정렬한다. total_score[x[0]] 는 장르의 총 점수를 기준으로 정렬하겠다는 의미이다. 만약 x[0]만 쓴다면 단어의 이름 순으로 정렬이 된다. x가 mlist의 key이고, 곧 장르 이름이기 때문이다. 그래서 동일한 총 점수를 가진 것들에서는 무작위로 정렬이 이루어질 수 있다. 그렇기 때문에 total_score[x[0]] 으로 써줘야 한다.
for genre, info in mlist: #장르, 노래정보
for idx, play in sorted(info, key= lambda x: x[1], reverse=True)[:2]:
answer.append(idx)
return answer
이제 mlist는 장르의 전체 플레이 횟수대로 정렬된 상태이다. (장르, (idx, play 횟수)) 이 상태로 정렬되어 있는데, 이제 두 번째 조건인 play 횟수가 큰 순으로 정렬을 해주어야 한다. 그래서 info를 꺼내고, 이 안에서 play횟수에 해당하는 x[1] 순으로 정렬해준다. 그리고 reverse=True를 해서 내림차순을 만들어준다. 마지막에 [:2]는 [0,1]에 해당하며 2개만 꺼내겠다는 의미이다.
개인 취향이지만 dict문제는 다른 유형보다 조금 더 재밌는 것 같다. 이 문제 역시 dict 문제들 중에서도 재밌는 문제였다. lambda에 대해 공부하고 싶다면 좋은 문제인 것 같다.
'코딩테스트 대비 > 프로그래머스' 카테고리의 다른 글
| [Python][프로그래머스] lv3. 섬 연결하기 (1) | 2023.10.06 |
|---|---|
| [Python][프로그래머스] lv3. 디스크 컨트롤러 (0) | 2023.10.05 |
| [Python][프로그래머스] lv3. 보석 쇼핑 (0) | 2023.09.27 |
| [Python][프로그래머스] lv2. 전화번호 목록 (0) | 2023.07.10 |
| [Python][프로그래머스] lv3. 여행경로 (0) | 2023.07.09 |