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(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
(이 경우는 lambda : defaultdict(int)
) 의 인수 가 호출되고 반환 값은이 키의 새로운 값으로 설정됩니다. 우리의 경우는의 값이 d[Key_dont_exist]
될 것입니다 defaultdict(int)
, 당신은 즉이 마지막 defaultdict에서 키에 액세스하려고하면 d[Key_dont_exist][Key_dont_exist]
그것이 마지막의 인수의 반환 값은 0 리턴 defaultdict
즉 int()
, 희망이 도움이되었다.
defaultdict
는 함수 여야합니다. defaultdict(int)
사전이며, 사전 lambda: defaultdict(int)
을 반환하는 함수입니다.
defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
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 문서-콜렉션을 참조하십시오.
d = defaultdict(lambda : Counter())
보다는 사용하고 싶을 것 d = defaultdict(lambda : defaultdict(int))
입니다.
d = defaultdict(Counter())
이 경우에 람다를 사용할 필요가 없습니다
Counter
객체 대신 호출 가능 항목을 전달하십시오 . 즉 :d = defaultdict(Counter)
참고로 다음을 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')
ndd = nested_defaultdict(dict) .... ndd['a']['b']['c']['d'] = 'e'
던지기KeyError: 'b'
depth=0
입니다. 호출시 깊이를 알 수없는 경우 항상 바람직하지 않을 수도 있습니다. if not depth: return default_factory()
더 우아한 솔루션이 있지만 함수 상단에 line을 추가하여 쉽게 수정할 수 있습니다.
이전 답변에서는 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 개의 항목 튜플을 사용하십시오.