defaultdict(defaultdict(int))
다음 코드를 작동시킬 수 있는 방법이 있습니까?
for x in stuff:
d[x.a][x.b] += x.c_int
d
요구에 따라 임시을 구축 할 x.a
및 x.b
요소.
나는 사용할 수있다 :
for x in stuff:
d[x.a,x.b] += x.c_int
그러나 나는 사용할 수 없었습니다 :
d.keys()
d[x.a].keys()
답변
예, 이런 식으로 :
defaultdict(lambda: defaultdict(int))
존재하지 않는 키에 액세스하려고 하면 defaultdict
(이 경우는 lambda: defaultdict(int)
) 의 인수 가 호출됩니다. 그것의 반환 값은이 키의 새로운 값으로 설정 될 것이며,이 경우 우리의 값은 d[Key_doesnt_exist]
입니다 defaultdict(int)
.
이 마지막 defaultdict에서 키에 액세스하려고하면, 즉 d[Key_doesnt_exist][Key_doesnt_exist]
0이 리턴됩니다 int()
. 즉, 마지막 defaultdict 인수의 리턴 값입니다 .
답변
defaultdict 생성자에 대한 매개 변수는 새 요소를 빌드하기 위해 호출되는 함수입니다. 람다를 사용하자!
>>> from collections import defaultdict
>>> d = defaultdict(lambda : defaultdict(int))
>>> print d[0]
defaultdict(<type 'int'>, {})
>>> print d[0]["x"]
0
Python 2.7부터 Counter를 사용 하는 더 나은 솔루션이 있습니다 .
>>> from collections import Counter
>>> c = Counter()
>>> c["goodbye"]+=1
>>> c["and thank you"]=42
>>> c["for the fish"]-=5
>>> c
Counter({'and thank you': 42, 'goodbye': 1, 'for the fish': -5})
일부 보너스 기능
>>> c.most_common()[:2]
[('and thank you', 42), ('goodbye', 1)]
자세한 정보는 PyMOTW-콜렉션-컨테이너 데이터 유형 및 Python 문서-콜렉션을 참조하십시오.
답변
사용하는 것이 조금 더 우아하다는 것을 알았습니다 partial
.
import functools
dd_int = functools.partial(defaultdict, int)
defaultdict(dd_int)
물론 이것은 람다와 동일합니다.
답변
참고로 다음을 defaultdict
통해 일반 중첩 팩토리 메소드 를 구현할 수 있습니다 .
from collections import defaultdict
from functools import partial
from itertools import repeat
def nested_defaultdict(default_factory, depth=1):
result = partial(defaultdict, default_factory)
for _ in repeat(None, depth - 1):
result = partial(defaultdict, result)
return result()
깊이는에 정의 된 유형 default_factory
이 사용 되기 전에 중첩 된 사전의 수를 정의합니다 . 예를 들면 다음과 같습니다.
my_dict = nested_defaultdict(list, 3)
my_dict['a']['b']['c'].append('e')
답변
이전 답변에서는 2 단계 또는 n 단계를 만드는 방법을 설명했습니다 defaultdict
. 어떤 경우에는 무한한 것을 원합니다.
def ddict():
return defaultdict(ddict)
용법:
>>> d = ddict()
>>> d[1]['a'][True] = 0.5
>>> d[1]['b'] = 3
>>> import pprint; pprint.pprint(d)
defaultdict(<function ddict at 0x7fcac68bf048>,
{1: defaultdict(<function ddict at 0x7fcac68bf048>,
{'a': defaultdict(<function ddict at 0x7fcac68bf048>,
{True: 0.5}),
'b': 3})})
답변
다른 사람들은 다음을 작동시키는 방법에 대한 귀하의 질문에 올바르게 대답했습니다.
for x in stuff:
d[x.a][x.b] += x.c_int
다른 방법은 키에 튜플을 사용하는 것입니다.
d = defaultdict(int)
for x in stuff:
d[x.a,x.b] += x.c_int
# ^^^^^^^ tuple key
이 방법의 장점은 간단하고 쉽게 확장 할 수 있다는 것입니다. 3 단계 깊이의 매핑이 필요한 경우 키에 3 개의 항목 튜플을 사용하십시오.