import math
def solution(progresses, speeds):
zipped = zip(progresses, speeds)
days = [math.ceil((100-x)/y) for x, y in zipped]
max_index = [0]
ptr = 0
answer = []
for _ in range(len(days)):
if days[max_index[-1]] >= days[ptr]:
ptr +=1
else:
max_index.append(ptr)
ptr +=1
last_element = len(days)-max_index[-1]
for x in range(len(max_index)-1):
answer.append(max_index[x+1]-max_index[x])
answer.append(last_element)
return answer
- zip하지 않은 상태로 여러 개의 리스트를 list comprehension에 동시에 쓸 수 없나봐
- pop은 index를 파라미터로 갖는구나! 원소 그자체가 아니구.
모범 코드
1. math의 ceil을 사용하지 않음
def solution(progresses, speeds):
Q=[]
for p, s in zip(progresses, speeds):
if len(Q)==0 or Q[-1][0]<-((p-100)//s):
Q.append([-((p-100)//s),1])
else:
Q[-1][1]+=1
return [q[1] for q in Q]
2. 군더더기 없이 담백하게 자료구조를 잘 녹여냄
def solution(progresses, speeds):
print(progresses)
print(speeds)
answer = []
time = 0
count = 0
while len(progresses)> 0:
if (progresses[0] + time*speeds[0]) >= 100:
progresses.pop(0)
speeds.pop(0)
count += 1
else:
if count > 0:
answer.append(count)
count = 0
time += 1
answer.append(count)
return answer
1. 장르 정렬: 곡수 2. 장르 내 곡 정렬: 재생량 / 같으면 고유번호 낮은 거 먼저.
입력 2개: 노래 장르 list, 노래별 재생횟수 list return: 베스트앨범 내 노래 고유번호 list
코드
def solution(genres, plays):
gen_type = set(genres)
gen_dict = {hash(a):0 for a in gen_type} #dictionary comprehension
genres = [hash(b) for b in genres] #list comprehension
zipped = list(enumerate(list(zip(genres, plays)))) #enumerate 통해 index 반환
for item in zipped:
gen_dict[item[1][0]] += item[1][1]
gen_dict = sorted(gen_dict.items(), key=lambda x : x[1], reverse=True) #how to sort dictionary #method 'sort' is not available
gen_sort = [x for x in list(map(lambda x: x[0], gen_dict))] #곡 재생수가 가장 큰 순으로 장르 나열
answer=[]
for gen in gen_sort:
a=[] #장르별 곡 리스트
for zips in zipped:
if zips[1][0]==gen:
a.append(zips)
else:
continue
a.sort(key=lambda x: x[1][1], reverse=True)
answer+=[x for x in list(map(lambda x: x[0], a[:2]))]
return answer
주요 도구
- 알고리즘: 해시(딕셔너리, 파이썬 hash 함수)
- dictionary comprehension: 딕셔너리 생성하여 각 장르를 key, 장르별 곡 재생수의 총합을 value로 정리함
- zip(리스트1, 리스트2)에 list를 한번 더 씌워야 함 => 각 튜플에도 다중 인덱스로 접근 가능
- index 정보를 반환해주는 enumerate에도 list를 한번 더 씌워야 함 => 마찬가지, 각 원소에 다중 인덱스로 접근 가능
- 기존에 value값이 0으로 저장된 딕셔너리에 [] 인덱스 통해 => 적절한 key값을 입력해줌
- 특정 기준으로 iterable 정렬하기: sorted & key & lambda의 조합! lambda 통해 iterable의 '각 원소'에 구체적으로 접근 가능.
-딕셔너리 정렬: 메서드 sort 대신 함수 sorted, 단.items()메소드 붙여야 함!
- map & lambda 조합 역시 중요: 주어진 이터러블 '각 원소'에 '동시에' 특정 함수를 적용하고 싶을 때.
map(함수, 이터러블) => map(lambda x: x~~, 이터러블)
마찬가지 map 이후 list 한번 더 씌워야 함.
- continue는 for문 처음으로 다시 돌아가는 것 vs return은 for문을 포함하여 함수 전체를 종료시키는 것
- indentation 아주 중요함. 엄밀한 논리 & 초반에 정확한 설계
다른 사람의 모범 풀이
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