베스트앨범

문제정의


베스트 앨범에 곡을 넣는 문제이다. 우선순위는 다음과 같다.

  1. 재생 횟수가 가장 많은 장르를 먼저 배치한다.
  2. 장르 안에서 재생 횟수가 많은 곡 두개를 넣는다. 곡이 하나라면 하나만 넣는다.
  3. 재생 횟수가 동일할 경우 고유번호(인덱스)가 낮은 것을 우선 배치한다.

문제 링크

문제풀이


이번 문제는 기존 내 코드와 파이써닉하게 작성된 코드를 비교하려고 한다. 이건 기존에 혼자 풀이한 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def solution(genres, plays):
answer = []
genre_dict = {}

for i, genre in enumerate(genres):
if genre_dict.get(genre) is None:
genre_dict[genre] = plays[i]
else:
v = genre_dict.get(genre)
genre_dict[genre] = v + plays[i]

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

for el in sorted_dict:
song_dict = {}
for i, genre in enumerate(genres):
if genre == el[0]:
song_dict[i] = plays[i]

sorted_song_dict = sorted(song_dict.items(), key = (lambda x : x[1]), reverse = True)
for i, item in enumerate(sorted_song_dict):
if i > 1:
break
answer.append(item[0])


return answer

genre_dict는 장르별로 총 플레이 횟수를 저장하기 위한 딕셔너리이다. enumerate를 활용하여 장르가 저장되어 있지 않은 경우 새로 등록을 하고, 이미 있는 경우에는 저장된 값에 현재 재생횟수를 추가한다.

genre_dictsorted를 활용하여 값을 기준으로 내림차순 정렬을 한다. 이렇게 하면 1번 조건을 만족할 수 있게 된다.

이제 2,3번에 관한 처리를 해야한다. sorted_dict에서 값을 꺼내면서 장르마다 그 장르에 속하는 곡을 찾아낸다. 곡을 찾을 경우 곡의 인덱스를 키로 하고 재생횟수를 값으로 하여 딕셔너리에 추가한다.

이 뒤는 1번과 비슷하다. sorted를 다시 활용하여 값을 기준으로 내림차순 정렬한다(sorted_song_dict).

이제 여기서 2개씩 꺼내서 answer리스트에 추가한다. 들어있는 요소가 한개라면 하나만 넣고 종료한다.

알고리즘은 똑같다. 하지만 파이써닉 하게 작성한 코드를 보면 코드 라인이 확실히 줄어든다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def solution(genres, plays):
ht1 = dict()
ht2 = dict()

for i, elem in enumerate(zip(genres, plays)):
g, p = elem
if g not in ht1:
ht1[g] = 0
ht2[g] = []

ht1[g] += p
ht2[g].append((i, p))
#(g,p) # -p 내림차순!
sort_ht1 = sorted(list(ht1.items()), key = lambda x: -x[1])

for g,p in sort_ht1:
sort_ht2 = sorted(ht2[g], key= lambda x: -x[1])
answer += list(map(lambda x : x[0], sort_ht2))[:2]

return answer
  1. zip을 통해 기존 인덱스 접근과는 다른 접근 방식을 보여준다.
  2. sorted에서 람다함수 부분을 보면 reverse속성이 없고 대신 값에 마이너스를 취한 것을 볼 수 있다. 기능의 차이는 없지만 이렇게 한 경우 코드가 더 간결해 보인다.
  3. maplambda를 활용하여 곡의 고유번호 2개를 가져온다. 이때 list로 묶에 슬라이싱을 한다.

테스트


테스트 화면


통과는 하였지만 파이써닉하게 푸는 것은 아직 더 공부가 필요할 것 같다.