가장 많이 사용하는 자료구조인 dictionary.
어떠한 key의 value가 존재하지 않을 때 처리하는 방법을 알아보자.
주어진 리스트에서 알파벳의 개수를 세어보자.
ex)
input : ['a', 'b', 'c', 'd', 'd', 'e', 'a', 'b', 'c', 'c', 'd', 'd', 'd', 'a', 'c']
expected output : {'a': 3, 'b': 2, 'c': 4, 'd': 5, 'e': 1}
def count_alphabet(input):
result = {}
for letter in input:
if letter not in result:
result[letter] = 0
result[letter] += 1
return result
if 조건문으로 result안에 letter가 key로 존재하지 않는 경우 해당 key에 대한 value를 0으로 지정하였다.
쉽게 생각할 수 있는 방법이지만 가독성 측면에서 좋지 않다.
dict.setdefault
dict 안에 key가 없으면 지정된 default value로 key를 삽입한다.
key가 dict안에 있으면 해당 key의 value를 반환하고 그렇지 않으면 default value를 반환한다.
def count_alphabet(input):
result = {}
for letter in input:
result.setdefault(letter, 0)
result[letter] += 1
return result
setdefault 함수는 첫번째 인자로 key, 두번째 인자로 default value를 지정한다.
한결 코드가 깔끔해졌지만 for loop 내에서 setdefault 함수가 무조건적으로 호출되므로 좋지 않아 보인다.
내장모듈인 collections의 defaultdict 클래스를 사용하자
defaultdict class
defaultdict class의 constructor(생성자)로 기본값을 생성해주는 함수를 넘기면 모든 key에 대해 value가 없을 경우 생성자의 인자로 넘어온 함수를 호출하여 그 값으로 설정한다.
int로 설정하면 기본값이 0, dict나 list는 비어있는 dict {}, list []가 된다.
다른 값으로 설정하고 싶다면 lamda를 사용한다.
from collections import defaultdict
def count_alphabet(input):
result = defaultdict(int)
for letter in input:
result[letter] += 1
return result
# result :
defaultdict(<class 'int'>, {'a': 3, 'b': 2, 'c': 4, 'd': 5, 'e': 1})
from collections import defaultdict
def count_alphabet(input):
result = defaultdict(lambda: 0)
for letter in input:
result[letter] += 1
return result
# result :
defaultdict(<function countAlphabet2.<locals>.<lambda> at 0x0000029E74FF89D0>, {'a': 3, 'b': 2, 'c': 4, 'd': 5, 'e': 1})
적절한 때에 setdefault / defaultdict를 자유자재로 사용할 수 있도록 알아둡시다.