디폴트 딕셔너리

defaultdict는 사전의 하위 클래스( dict, 이전 게시물 참조)이므로 추가 기능과 함께 dict에서 대부분의 동작을 상속합니다. 이러한 기능이 어떻게 다른지, 어떤 경우에는 더 편리하게 만드는지 이해하려면 몇 가지 오류가 발생해야 합니다.

문서에서 단어 수를 계산하려고 하면 일반적인 접근 방식은 사전keys이 단어이고 사전values이 해당 단어의 수인 사전을 만드는 것입니다.

일반 사전을 사용하여 이 작업을 수행해 보겠습니다.

먼저 설정을 위해 단어 목록과 split()를 개별 단어로 가져옵니다. 나는 another project에서 이 단락을 가져왔고 특정 단어가 두 번 이상 표시되도록 인위적으로 몇 가지 추가 단어를 추가했습니다(곧 이유가 밝혀질 것입니다).


# paragraph
lines = ["This table highlights 538's new NBA statistic, RAPTOR, in addition to the more established Wins Above Replacement (WAR). An extra column, Playoff (P/O) War, is provided to highlight stars performers in the post-season, when the stakes are higher. The table is limited to the top-100 players who have played at least 1,000 minutes minutes the table Wins NBA NBA RAPTOR more players"]

# split paragraphy into individual words
lines = " ".join(lines).split()

type(lines) # list


이제 lines 목록이 있으므로 dict라는 빈 word_counts을 만들고 각 단어가 key이고 각 value가 해당 단어의 개수가 되도록 합니다.

# empty list
word_counts = {}

# loop through lines to count each word
for word in lines:
    word_counts[word] += 1

# KeyError: 'This'


목록이 존재하지 않는 키를 계산하려고 했기 때문에 KeyError(즉, 'This')의 맨 처음 단어에 대해 lines를 받았습니다. tryexcept 를 사용할 수 있도록 예외를 처리하는 방법을 배웠습니다.

여기에서 lines를 반복하고 있으며 이전에 했던 것처럼 존재하지 않는 키를 계산하려고 할 때 이제 KeyError를 예상하고 초기 개수를 1로 설정할 수 있습니다. 루프스루를 계속하고 현재 존재하는 단어를 세어 증가할 수 있습니다.

# empty list
word_counts = {}

# exception handling
for word in lines:
    try:
        word_counts[word] += 1
    except KeyError:
        word_counts[word] = 1

# call word_counts
# abbreviated for space
word_counts

{'This': 1,
 'table': 3,
 'highlights': 1,
 "538's": 1,
 'new': 1,
 'NBA': 3,
 'statistic,': 1,
 'RAPTOR,': 1,
 'in': 2,
 'addition': 1,
 'to': 3,
 'the': 5,
 'more': 2,
 ...
 'top-100': 1,
 'players': 2,
 'who': 1,
 'have': 1,
 'played': 1,
 'at': 1,
 'least': 1,
 '1,000': 1,
 'minutes': 2,
 'RAPTOR': 1}


이제 위의 사항을 달성하는 다른 방법이 있습니다.

# use conditional flow
word_counts = {}

for word in lines:
    if word in word_counts:
        word_counts[word] += 1
    else:
        word_counts[word] = 1

# use get
for word in lines:
    previous_count = word_counts.get(word, 0)
    word_counts[word] = previous_count + 1


여기에서 저자가 defaultdict 에 대해 앞서 언급한 두 가지 접근 방식이 적합하지 않다고 주장합니다. 우리는 전통적인 defaultdict 대신 dict 를 사용하여 첫 번째 접근 방식을 시도하기 위해 완전한 원으로 돌아올 것입니다.
defaultdictdict의 하위 클래스이며 collections에서 가져와야 합니다.

from collections import defaultdict

word_counts = defaultdict(int)

for word in lines:
    word_counts[word] += 1

# we no longer get a KeyError
# abbreviated for space
defaultdict(int,
            {'This': 1,
             'table': 3,
             'highlights': 1,
             "538's": 1,
             'new': 1,
             'NBA': 3,
             'statistic,': 1,
             'RAPTOR,': 1,
             'in': 2,
             'addition': 1,
             'to': 3,
             'the': 5,
             'more': 2,
             ...
             'top-100': 1,
             'players': 2,
             'who': 1,
             'have': 1,
             'played': 1,
             'at': 1,
             'least': 1,
             '1,000': 1,
             'minutes': 2,
             'RAPTOR': 1})



일반 사전과 달리 defaultdict 가 포함하지 않은 키를 조회하려고 할 때 defaultdict 를 처음 만들 때 제공한 인수를 사용하여 자동으로 값을 추가합니다. 위를 보면 int를 인수로 입력하여 정수 값을 자동으로 추가할 수 있습니다.
defaultdictvalueslists가 되도록 하려면 list를 인수로 전달할 수 있습니다. 그런 다음 append 값을 입력하면 자동으로 list 에 포함됩니다.

dd_list = defaultdict(list) # defaultdict(list, {})

dd_list[2].append(1)        # defaultdict(list, {2: [1]})

dd_list[4].append('string') # defaultdict(list, {2: [1], 4: ['string']})


dictdefaultdict 로 전달할 수도 있습니다. 추가된 모든 값이 dict 에 포함되도록 합니다.


dd_dict = defaultdict(dict) # defaultdict(dict, {})

# match key-with-value
dd_dict['first_name'] = 'lebron' # defaultdict(dict, {'first_name': 'lebron'})
dd_dict['last_name'] = 'james'   

# match key with dictionary containing another key-value pair
dd_dict['team']['city'] = 'Los Angeles'

# defaultdict(dict,
#            {'first_name': 'lebron',
#             'last_name': 'james',
#             'team': {'city': 'Los Angeles'}})



응용 프로그램: defaultdict를 사용한 그룹화



다음 예제는 Python의 모든 것에 대한 환상적인 리소스인 Real Python에서 가져온 것입니다.
defaultdict 를 사용하여 시퀀스 또는 컬렉션의 항목을 그룹화하고 초기 매개변수(일명 .default_factory )를 list 로 설정하는 것이 일반적입니다.

dep = [('Sales', 'John Doe'),
       ('Sales', 'Martin Smith'),
       ('Accounting', 'Jane Doe'),
       ('Marketing', 'Elizabeth Smith'),
       ('Marketing', 'Adam Doe')]

from collections import defaultdict

dep_dd = defaultdict(list)

for department, employee in dep:
    dep_dd[department].append(employee)

dep_dd
#defaultdict(list,
#            {'Sales': ['John Doe', 'Martin Smith'],
#             'Accounting': ['Jane Doe'],
#             'Marketing': ['Elizabeth Smith', 'Adam Doe']})



항목이 중복되면 어떻게 됩니까? set 중복을 처리하고 고유한 항목만 그룹화하기 위해 약간 앞으로 나아가고 있습니다.


# departments with duplicate entries
dep = [('Sales', 'John Doe'),
       ('Sales', 'Martin Smith'),
       ('Accounting', 'Jane Doe'),
       ('Marketing', 'Elizabeth Smith'),
       ('Marketing', 'Elizabeth Smith'),
       ('Marketing', 'Adam Doe'),
       ('Marketing', 'Adam Doe'),
       ('Marketing', 'Adam Doe')]

# use defaultdict with set
dep_dd = defaultdict(set)

# set object has no attribute 'append'
# so use 'add' to achieve the same effect
for department, employee in dep:
    dep_dd[department].add(employee)

dep_dd
#defaultdict(set,
#            {'Sales': {'John Doe', 'Martin Smith'},
#             'Accounting': {'Jane Doe'},
#             'Marketing': {'Adam Doe', 'Elizabeth Smith'}})


응용 프로그램: defaultdict로 누적



마지막으로 defaultdict를 사용하여 값을 누적합니다.

incomes = [('Books', 1250.00),
           ('Books', 1300.00),
           ('Books', 1420.00),
           ('Tutorials', 560.00),
           ('Tutorials', 630.00),
           ('Tutorials', 750.00),
           ('Courses', 2500.00),
           ('Courses', 2430.00),
           ('Courses', 2750.00),]

# enter float as argument        
dd = defaultdict(float)  # collections.defaultdict

# defaultdict(float, {'Books': 3970.0, 'Tutorials': 1940.0, 'Courses': 7680.0})
for product, income in incomes:
    dd[product] += income

for product, income in dd.items():
    print(f"Total income for {product}: ${income:,.2f}")

# Total income for Books: $3,970.00
# Total income for Tutorials: $1,940.00
# Total income for Courses: $7,680.00

defaultdictdictionaries가 열의 값을 그룹화, 계산 및 누적하는 데 유용할 수 있음을 알 수 있습니다. 데이터 과학 응용 프로그램이 더 명확해지면 이러한 기본 개념을 다시 살펴보겠습니다.

요약하면 dictionariesdefaultdict 항목을 그룹화하고 항목을 누적하고 항목을 계산하는 데 사용할 수 있습니다. 둘 다 key가 (아직) 존재하지 않는 경우에도 사용할 수 있지만 defaultdict가 이것을 더 간결하게 처리합니다. 지금은 여기에서 멈추고 다음 주제인 카운터로 넘어갈 것입니다.


데이터 과학, 기계 학습, R, Python, SQL 등에 대한 자세한 내용은 .

좋은 웹페이지 즐겨찾기