본문 바로가기
프로그래머스/Lv.3

베스트앨범 - Python, defaultdict, sort, sorted

by 아찌방 2024. 11. 6.

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/42579

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

 

풀이 - 나의 생각

이 문제는 너무 복잡해서

 

풀기 위해서는 단계별로 접근 할 필요가 있다.

 

# 1.장르별 합산
# 2.장르별 분리(index, genre, play)
# 3.장르별 정렬
# 4.베스트 앨범 결정 (1번 결과 기준으로 순서 결정)

 


# 0. defaultdict

 

defaultdict는 collections 모듈에 있는 파이썬의 특별한 딕셔너리 유형으로,

 

기본 값을 자동으로 설정해주는 기능을 가지고 있습니다.

 

기존의 딕셔너리는 값을 선언할 때 Key, Value 모두 선언해주어야 하는데

 

defaultdict는 value가 빈 상태로 만들어 줍니다.

 

예시로

 

from collections import defaultdict

# int를 기본값으로 설정하면 초기 값은 0
num_dict = defaultdict(int)
num_dict['a'] += 1  # 'a'가 없기 때문에 기본값 0이 할당되고, 이후에 +1이 되어 1이 됨
num_dict['b'] += 2  # 'b'도 마찬가지로 기본값 0에서 +2가 되어 2가 됨

print(num_dict)  # 출력: defaultdict(<class 'int'>, {'a': 1, 'b': 2})

 

from collections import defaultdict

# 기본값이 빈 리스트인 defaultdict
list_dict = defaultdict(list)
list_dict['fruits'].append('apple')  # 'fruits'가 없으므로 빈 리스트가 기본값으로 설정됨
list_dict['fruits'].append('banana')

print(list_dict)  # 출력: defaultdict(<class 'list'>, {'fruits': ['apple', 'banana']})

 


# 1.장르별 합산

 

genre_play_count = defaultdict(int)
    for genre, play in zip(genres, plays):
        genre_play_count[genre] += play
        
print(genre_play_count) #출력 : defaultdict(<class 'int'>, {'classic': 1450, 'pop': 3100})

 

장르별 재생 횟수를 저장해줍니다.


# 2.장르별 분리(index, genre, play)

 

genre_score_dict = defaultdict(list)
    for idx, (genre, play) in enumerate(zip(genres, plays)):
        genre_score_dict[genre].append((play, idx))
print(genre_score_dict)
#출력 : defaultdict(<class 'list'>, {'classic': [(500, 0), (150, 2), (800, 3)], 'pop': [(600, 1), (2500, 4)]})

 

장르별로 해당 음악의 재생 횟수와 위치를 저장해줍니다.

 


# 3.장르별 정렬

 

for genre in genre_score_dict:
        genre_score_dict[genre].sort(key = lambda x: (-x[0], x[1]))
print(genre_score_dict)
#출력 : defaultdict(<class 'list'>, {'classic': [(800, 3), (500, 0), (150, 2)], 'pop': [(2500, 4), (600, 1)]})

 

장르별로

 

재생 횟수로 내림차순, 인덱스로 오름차순으로 정렬을 진행해줍니다.


# 4.베스트 앨범 결정 (1번을 정렬한 기준으로 순서 결정)

 

1) 장르별 재생횟수 합산을 비교해서 정렬해줍니다.

sorted_genre = sorted(genre_play_count.keys(), key = lambda g: genre_play_count[g], reverse=True)
print(sorted_genre) #출력 : ['pop', 'classic']

 

2) 1) 순서로 앞에서 2개를 잘라 가져옵니다.

best_album = []
for genre in sorted_genre:
	best_album.extend(song[1] for song in genre_score_dict[genre][:2])

 

위의 과정을 거치면

 

정답에 도달할 수 있습니다.

 

코드

 

# 1.장르별 합산
# 2.장르별 분리(index, genre, play)
# 3.장르별 정렬
# 4.베스트 앨범 결정 (1번 결과 기준으로 순서 결정)

from collections import defaultdict

def solution(genres, plays):
    genre_play_count = defaultdict(int)
    for genre, play in zip(genres, plays):
        genre_play_count[genre] += play
    
    genre_score_dict = defaultdict(list)
    for idx, (genre, play) in enumerate(zip(genres, plays)):
        genre_score_dict[genre].append((play, idx))
    
    for genre in genre_score_dict:
        genre_score_dict[genre].sort(key = lambda x: (-x[0], x[1]))
    
    sorted_genre = sorted(genre_play_count.keys(), key = lambda g: genre_play_count[g], reverse=True)
    best_album = []
    for genre in sorted_genre:
        best_album.extend(song[1] for song in genre_score_dict[genre][:2])
    
    return best_album

 

 

 

 

 

 

 

다음에 또 봐요

 

728x90