Python에서 Defaultdict의 Defaultdict 만들기
Python에는 범용 이데올로기를 가진 dict, list, set 및 tuple과 같은 내장 컨테이너가 있습니다. 이러한 범용 컨테이너를 확장하거나 개선하기 위해 Python은 Python 컬렉션이라는 특수 컨테이너 데이터 유형을 도입하는 모듈을 제공합니다.
이러한 특수 컨테이너 데이터 유형 중 하나는 기본 Python 사전(dict)에 대한 훌륭한 대안(및 하위 클래스)인 defaultdict입니다. defaultdict를 사용하면 누락된 값을 제공하는 factory 기능을 제공할 수 있습니다(KeyError 예외 또는 메시지가 아님).
따라서 키가 사전에 없으면 factory 함수가 호출되어 KeyError 예외를 발생시키는 대신 값을 반환합니다.
defaultdict를 사용하는 것은 상대적으로 간단할 수 있지만 defaultdict의 defaultdict로 작업하는 것은 혼란스러울 수 있습니다. 이 문서에서는 오류를 발생시키지 않고 defaultdict의 defaultdict를 생성하는 방법과 내부 작업이 어떻게 발생하는지 설명합니다.
lambda를 사용하여 Python에서 Defaultdict의 Defaultdict 생성
Python 컬렉션과 본질적으로 defaultdict를 사용하려면 Python 표현식을 사용하여 collection 모듈을 가져올 수 있습니다.
from collections import defaultdict
defaultdict는 다음 Python 표현식에서 확인할 수 있는 dict 클래스의 하위 클래스입니다.
issubclass(defaultdict, dict)
출력:
True
dict를 사용하면 존재하지 않는 키가 사전에 전달될 때 __missing__ 메서드가 트리거됩니다. 이 메서드는 default_factory 속성이 None으로 설정되어 KeyError 예외가 발생합니다. 그러나 default_dict를 사용하면 존재하지 않는 키가 사전에 전달될 때 기본값을 반환하는 factory를 보유하는 __missing__ 메서드의 default_factory 속성을 트리거합니다.
예를 들어 존재하지 않는 키가 전달될 때 빈 목록을 반환하는 factory 함수 list를 포함하는 defaultdict 사전을 가질 수 있습니다.
from collections import defaultdict
ddict = defaultdict(list)
print(ddict["one"])
출력:
[]
ddict에는 one 키가 없지만 factory 함수가 전달되기 때문에 빈 목록의 값을 반환합니다. 그러한 식 뒤에 키를 생성하기도 합니다.
from collections import defaultdict
ddict = defaultdict(list)
print(ddict["one"])
print(ddict["two"].append(1))
print(ddict)
출력:
[]
defaultdict(<class 'list'>, {'one': [], 'two': [1]})
따라서 ddict["one"] 및 ddict["two"].append(1) 문 다음에 list 기능을 기반으로 해당 키와 해당 값을 생성합니다. 두 번째 Python 문의 경우 default_factory 속성 함수를 기반으로 빈 목록을 만든 다음 값 1을 추가합니다.
defaultdict 데이터 유형 내의 일반적인 값 그룹화는 dict 데이터 유형과 다르게 처리할 수 있습니다.
sentence = "the man loves oranges, but also cares a great deal about apples"
letterStore = dict()
for i in sentence:
if k not in letterStore:
letterStore[i] = 1
continue
letterStore[i] += 1
print(letterStore.items())
출력:
dict_items([('t', 4), ('h', 1), ('e', 7), (' ', 11), ('m', 1), ('a', 9), ('n', 2), ('l', 4), ('o', 4), ('v', 1), ('s', 5), ('r', 3), ('g', 2), (',', 1), ('b', 2), ('u', 2), ('c', 1), ('d', 1), ('p', 2)])
위의 문자 그룹화는 대신 defaultdict를 사용하여 쉽게 수행할 수 있습니다. 초기 번호 매기기를 생성하기 위해 문자가 이미 letterStore 바인딩에 있는지 확인하는 코드 블록을 사용하는 대신 defaultdict를 사용하여 factory 기능인 int를 통해 이를 달성할 수 있습니다.
from collections import defaultdict
sentence = "the man loves oranges, but also cares a great deal about apples"
letterStore = defaultdict(int)
for i in sentence:
letterStore[i] += 1
print(letterStore.items())
출력:
dict_items([('t', 4), ('h', 1), ('e', 7), (' ', 11), ('m', 1), ('a', 9), ('n', 2), ('l', 4), ('o', 4), ('v', 1), ('s', 5), ('r', 3), ('g', 2), (',', 1), ('b', 2), ('u', 2), ('c', 1), ('d', 1), ('p', 2)])
따라서 키가 존재하지 않을 때 __missing__ 메서드가 호출된다는 것을 알 수 있습니다. 속성 default_factory도 트리거되어 값을 반환하는 함수를 보유합니다.
그러나 defaultdict의 defaultdict를 만들 수 있습니까? 예, 하지만 어떻게 할 수 있습니까? defaultdict를 다른 defaultdict로 전달하면 오류가 발생하기 때문입니다.
from collections import defaultdict
d = defaultdict(defaultdict(int))
print(d)
출력:
Traceback (most recent call last):
File "c:\Users\USER\Desktop\JS\test.py", line 3, in <module>
d = defaultdict(defaultdict(int))
TypeError: first argument must be callable or None
코드를 실행할 때 TypeError가 발생하는데, 이는 d = defaultdict(defaultdict(int)) 라인 때문에 발생합니다. 첫 번째 인수는 호출 가능하거나 없음이어야 합니다.
이 정보를 통해 호출 가능(함수) 또는 없음(default_factory가 보유하는 기본값)을 전달하지 않았음을 추론할 수 있으며 이는 defaultdict(int)가 호출 가능하지 않기 때문입니다. 그러나 그것은 'collections.defaultdict'입니다.
따라서 lambda가 들어오는 콜러블을 전달할 방법을 찾아야 합니다.
lambda를 사용하면 호출할 수 있는(콜러블) 익명 함수를 만들 수 있습니다. 따라서 상위 레벨 defaultdict의 경우 존재하지 않는 키를 전달할 때 호출되는 defaultdict(int)를 가리키는 lambda 함수를 전달할 수 있습니다.
lambda 함수는 내부 defaultdict 내에서 factory 함수를 호출하고 키 값으로 설정될 값을 반환합니다.
from collections import defaultdict
d = defaultdict(lambda: defaultdict(int))
print(d)
출력:
defaultdict(<function <lambda> at 0x000001F6B9383E20>, {})
제대로 작동하는지 확인하기 위해 정사각형 표기법을 사용하여 최상위 defaultdict 및 내부 수준 defaultdict에 액세스하여 각각 lambda 및 int 함수에 전달되어야 하는 기본값을 확인할 수 있습니다. .
print(d[0])
print(d[0][0])
출력:
defaultdict(<class 'int'>, {})
0
Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.
LinkedIn