알고리즘/프로그래머스

[알고리즘 고득점 kit/해시] 베스트앨범

_jju 2026. 4. 28. 19:52

from collections import Counter

def solution(genres, plays):
    answer = []

    song_num = {}
    gr_sum = {}
    for i, gr in enumerate(genres):
        if gr not in song_num:
            song_num[gr] = []
        song_num[gr].append(i)
        gr_sum[gr] =  gr_sum.get(gr, 0) + plays[i]
    sorted_gr = sorted(gr_sum, key=lambda x:x[1], reverse=True)
    
    for gr in sorted_gr:
        lst = []
        for num in song_num[gr]:
            lst.append([num, plays[num]])
        sorted_song = sorted(lst, key=lambda x:x[1], reverse=True)
        for i in range(2 if len(sorted_song) >= 2 else 1):
            answer.append(sorted_song[i][0])
    return answer

틀림(20/100)

 

sorted_gr = sorted(gr_sum, key=lambda x:x[1], reverse=True)
이 줄 때문에 문제가 발생했다. 


일단 gr_sum 이라는 딕셔너리가 {클래식: 300, 팝:500} 이런 식으로 구성되어 있었다고 치자.

파이썬에서 딕셔너리를 그냥 sorted 함수에 넣으면, 기본적으로 딕셔너리의 key들만 정렬대상으로 뽑혀나온다. 그러니 저 문장을 실행하면 당연히 딕셔너리의 key의 1번째 인덱스, classic이라면 l이 정렬 기준이 되는 것이다. 

 

그러니 우린 딕셔너리를 그대로 sorted함수에 넣으면 안되고

sorted(gr_sum.items(), key=lambda x:x[1], reverse=True)

이렇게 items()를 붙여 튜플 리스트로 만들어줘야 key=lambda x:x[1]이 {classic, 300}에서 300을 나타내는 것이 된다.

 

이렇게 튜플 리스트 형태로 sorted_gr를 만들어뒀기에 for문에서도 주의해야한다. (장르, 총합) 여기서 총합은 안쓰더라도 언패킹해줘야 한다는 것

for gr, sum in sorted_gr:

 

+ 그리고 sorted() 함수에서 reverse = True로 오름차순을 구현할 수도 있지만
그냥 정렬기준인 key값에 마이너스를 달아도 같은 결과를 얻을 수 있다.

from collections import Counter

def solution(genres, plays):
    answer = []

    song_num = {}
    gr_sum = {}
    for i, gr in enumerate(genres):
        if gr not in song_num:
            song_num[gr] = []
        song_num[gr].append(i)
        gr_sum[gr] =  gr_sum.get(gr, 0) + plays[i]
    sorted_gr = sorted(gr_sum.items(), key=lambda x:x[1], reverse=True)
    
    for gr, sum in sorted_gr:
        lst = []
        for num in song_num[gr]:
            lst.append([num, plays[num]])
        sorted_song = sorted(lst, key=lambda x:(-x[1]))
        for i in range(2 if len(sorted_song) >= 2 else 1):
            answer.append(sorted_song[i][0])
    return answer

그리고 마지막에 최대 2개씩 answer리스트에 넣을 때

원래는 삼항연산자를 쓰려했는데 (조건 ? 참:거짓) 그걸 파이썬에서는

참 if~ else 거짓

이 형식으로 쓴다고 한다. 

 

이 부분은 슬라이싱 문법으로 더 쉽게 구현할 수 있는데

for song in sorted_song[:2]:

이렇게 쓰면 없어도 에러가 안나고 있는 것만 반환하기 때문이다.