[프로그래머스][해시] 완주하지 못한 선수

C++ 사용에 익숙해져 있어서 dict, list사용이 쉽지 않았다. 그리고 항상 VS Studio로 디버깅하다가 VS Code와 웹 IDE를 사용하려니 매우 어색했다. 지금은 처음이라 VS Code를 쓰면서 파이썬 내장 함수들에 익숙해지는 연습을 하고 있지만, 언젠가는 웹 IDE만을 사용하며 문제를 풀어야하기 때문에 얼른 파이썬과 친해지고 싶다.

1. 완주하지 못한 선수

내가 푼 풀이(첫 시도)

def solution(participant, completion):
    answer = ''
    cnt = dict()
    for i in participant:
        if (i in cnt):
            cnt[i] += 1
        else :
            cnt[i] = 1
    for i in completion:
        if (i in cnt):
            cnt[i] -= 1
        else :
            cnt[i] = 0
    for i in cnt:
        if(cnt[i] > 0):
            answer = i
    return answer

if와 else문을 넣지 않고 cnt[i] +=1 로 작성했을 때 keyerror가 떴는데, 검색해보니 dict에 존재하지 않는 key 값을 참조하려할 때 나오는 에러였다. if와 else를 덕지덕지 넣어서 어떻게 답은 맞춤.

내가 푼 풀이(두번째 시도)

from collections import defaultdict
def solution(participant, completion):
    answer = ''
    cnt = defaultdict(lambda: 0)
    for i in participant:
        cnt[i] += 1
    for i in completion:
        cnt[i] -= 1
    for i in cnt:
        if (cnt[i] > 0):
            answer += i
    return answer

위의 풀이와 비슷하지만 가장 큰 차이점은 defalutdict를 사용했다는 것이다. 더러웠던 if else문이 없어지니까 한결 보기 편함.

from collections import defaultdict

임포트 해준 뒤

cnt = defaultdict(lambda: 0)

이렇게 선언하면 초기값을 0으로 줄 수 있다.

Best 풀이

import collections

def solution(participant, completion):
    answer = collections.Counter(participant) - collections.Counter(completion)
    return list(answer.keys())[0]

이렇게 간단하게 풀 수 있다...
여기서 핵심은 collections.Counter 함수인데,

print(collections.Counter(participant))
>>> Counter({'leo': 1, 'kiki': 1, 'eden': 1})

print(collections.Counter(completion))
>>> Counter({'eden': 1, 'kiki': 1})

리스트/딕셔너리의 수를 세어 dict 형태로 return 해준다. 풀이와 같이 뺄셈도 가능하니 강력한 함수인 것 같다.

list(answer.keys())[0]

이 부분도 헷갈렸는데
1. answer가 collections.Counter의 뺄셈을 통해 dict 형태로 반환된다.
2. 딕셔너리.keys() 는 해당 딕셔너리의 모든 key 값(여기서는 선수의 이름)을 dict_keys라는 객체(not list)의 형태로 반환한 값이다.
3. 이를 list로 형변환하고, 가장 첫번째 인덱스 값을 가져온다. 여기서 첫번째 인덱스 값을 가져오는 이유는 문제에서 완주하지 못한 선수가 단 한 명이라고 제한했기 때문에 가능하다.

좋은 웹페이지 즐겨찾기