베스트앨범

szlee·2024년 11월 6일
0

알고리즘 PS

목록 보기
21/24

베스트앨범

def solution(genres, plays):
   
    answer = []
    
    music = dict()
    for i, (genre, play) in enumerate(zip(genres, plays)):
        if genre in music:
            music[genre].append((play, i))
        else:
            music[genre] = [(play, i)]
    
    music = sorted(music.items(), key=lambda x : sum(p for p, i in x[1]), reverse=True)
    music = [(gen, sorted(songs, key=lambda song : (-song[0], song[1]))) for gen, songs in music]

    for gen, songs in music:
        for song, idx in songs[:2]: 
            answer.append(idx)
    
    return answer
        

딕셔너리 만들고 나서 세개의 조건으로 정렬을 해야하는데
이 부분이 좀 까다롭다.

music = sorted(music.items(), key=lambda x : sum(p for p, i in x[1]), reverse=True)

딕셔너리의 .items() 메서드는 (key, value) 형태의 튜플로 구성된 리스트를 반환한다.

  • music = {'classic': [(500, 0), (150, 2), (800, 3)], 'pop': [(600, 1), (2500, 4)]}이면,
  • music.items() = [('classic', [(500, 0), (150, 2), (800, 3)]), ('pop', [(600, 1), (2500, 4)])]

x는 ('classic', [(500, 0), (150, 2), (800, 3)]) 이렇게 한 뭉탱이이고
x[0] = 'classic',
x[1] = [(500, 0), (150, 2), (800, 3)]이다.
x[1]의 첫번째 원소들의 합 기준으로 우선 정렬을 해야하므로, 또 for문을 돌려 sum을 한다.

다른 정렬을 함께 사용할 수 없는 이유는,
파이썬의 튜플 생성자는 제너레이터 표현식을 인자로 직접 사용할 수 없기 때문이다. 튜플 생성자는 단일 값을 받아들이기 때문에, 각 항목을 개별적인 값으로 전달해야 한다고 한다.
그래서 값이 하나로 나오는 sum부분은 가능하지만, p for p, i in x[1] 이런 부분이 튜플에서 불가한 것이다.
=> 결과 : [('pop', [(600, 1), (2500, 4)]), ('classic', [(500, 0), (150, 2), (800, 3)])] 리스트!

이제 재생수 내림차순, 인덱스 오름차순 기준으로 정렬해야한다.

music = [(genre, songs) for genre, songs in music]

요기서 songs 부분을 정렬해야 한다.

music = [(genre, sorted(songs, key=lambda song : (-song[0], song[1]))) for genre, songs in music]

[(600, 1), (2500, 4)] 이게 songs 부분.
key=lambda로 song (600, 1) 부분에서 song[0], song[1]로 나누어 정렬한다.

마지막으로 장르별로 두개씩 뽑으라했는데 있는 만큼 반환하기 위해 파이썬 인덱스 슬라이싱을 사용하였다.

profile
🌱

0개의 댓글