[Programmers / Python / 해시] - 베스트 앨범

Young·2021년 5월 8일
0

출처 https://programmers.co.kr/learn/courses/30/lessons/42579?language=python3

일단은 hash부터 만들기로 하고 코드를 작성하였다.

def solution(genres, plays):
    answer = []
    album_dict = {}
    tmp = []

    for i in range(len(genres)):
      
      if genres[i] in album_dict:
        tmp = []
        tmp.append((album_dict.get(genres[i])))
        tmp.append(plays[i])

        album_dict[genres[i]] = tmp

      else:
        album_dict[genres[i]] = plays[i]


    #return answer
    return album_dict

그런데 이런식으로 추가되었고 노래 번호도 저장하지 못한다는 문제가 있었다.
그래서 이를 해결하기 위해 dict을 두가지로 만들어보기로 했다.

문제의 조건1을 구하기 위해 genre_dict에 각 장르별 누적 재생수를 value로 넣어주고
문제의 조건2를 구하기 위해 play_dict에 각 노래의 (재생수, 고유 번호) tuple형태를 value로 넣어주었다.

def solution(genres, plays):
    answer = []
    genre_dict = {}
    play_dict = {}

    for i in range(len(genres)):
      if genres[i] in genre_dict:
        genre_dict[genres[i]] += plays[i]
        play_dict[genres[i]].append((plays[i], i))
      else:
        genre_dict[genres[i]] = plays[i]
        play_dict[genres[i]] = [(plays[i], i)]
      
    print(genre_dict)
    print(play_dict)
    
    return answe

dict을 각각 print 해봤다.
{'classic': 1450, 'pop': 3100}
{'classic': [(500, 0), (150, 2), (800, 3)], 'pop': [(600, 1), (2500, 4)]}

문제의 조건1을 위해 genre_dict를 내림차순 정렬했다.

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

{'classic': 1450, 'pop': 3100} 의 genre_dict.items()에서 value값을 기준으로 정렬해줘야 하기 때문에 key = lambda x: x[1]

play_dict는 장르 안에서만 정렬해주면 된다.
따라서 정렬된 genre_dict에서 장르를 하나씩 pop해서 해당 장르 내에서의 재생수를 내림차순 정렬해주고 상위 2곡의 고유 번호를 answer에 저장해줬다.

    while len(genre_dict)>0:
      max_genre = genre_dict.pop(0)[0]

      play_dict[max_genre].sort(key=lambda x:x[0], reverse = True)

      answer.append(play_dict[max_genre][0][1])
      answer.append(play_dict[max_genre][1][1])

    return answer

play_dict의 value는 (재생수, 고유번호) 이므로 key=lambda x:x[0] 를 통해 재생수를 기준으로 정렬해주었다.


테스트 케이스 중 몇 개가 실패했다.
각각 정렬되고 append되는 부분들을 다 print 해봤는데 틀린 부분이 없어 혹시 문제의 제한 사항 중에 구현하지 않은 부분이 있는지 확인해봤다.

장르에 속한 곡이 하나라면, 하나의 곡만 처리하는 부분은 구현을 해주지 않아서 이러한 케이스에서 오류가 발생한다고 판단했고 이 부분을 if else문을 통해 처리했다.

def solution(genres, plays):
    answer = []
    genre_dict = {}
    play_dict = {}

    for i in range(len(genres)):
      if genres[i] in genre_dict:
        genre_dict[genres[i]] += plays[i]
        play_dict[genres[i]].append((plays[i], i))
      else:
        genre_dict[genres[i]] = plays[i]
        play_dict[genres[i]] = [(plays[i], i)]
    
    genre_dict = sorted(genre_dict.items(), key = lambda x: x[1], reverse = True) #내림차순 정렬

    while len(genre_dict)>0:
      max_genre = genre_dict.pop(0)[0]

      play_dict[max_genre].sort(key=lambda x:x[0], reverse = True)

      if len(play_dict[max_genre]) > 1:
        answer.append(play_dict[max_genre][0][1])
        answer.append(play_dict[max_genre][1][1])
      else:
        answer.append(play_dict[max_genre][0][1])
    
    return answer

다른 사람의 풀이

def solution(genres, plays):
    answer = []
    d = {e:[] for e in set(genres)}
    for e in zip(genres, plays, range(len(plays))):
        d[e[0]].append([e[1] , e[2]])
    genreSort =sorted(list(d.keys()), key= lambda x: sum( map(lambda y: y[0],d[x])), reverse = True)
    for g in genreSort:
        temp = [e[1] for e in sorted(d[g],key= lambda x: (x[0], -x[1]), reverse = True)]
        answer += temp[:min(len(temp),2)]
    return answer

파이썬은 정말 다양한 내장 함수와 모듈들을 많이 알수록 코드가 Pythonic 해지는거 같다.
많은 문제를 경험하고 공부해서 더 간결하게 구현할 수 있도록 노력해야겠다...!

정리

sort() sorted()에서 key lambda 사용하기

iterable.sort(key=len, reverse=True)

길이순 내림차순 정렬

result = sorted(iterable, key=lambda x:x[0], reverse=False) 

각 원소의 index 0 을 기준으로 오름차순 정렬

profile
👩🏻‍💻

0개의 댓글

관련 채용 정보