Python : defaultdict를 dict로 변환


90

defaultdict를 어떻게 변환 할 수 있습니까?

number_to_letter
defaultdict(<class 'list'>, {'2': ['a'], '3': ['b'], '1': ['b', 'a']})

일반적인 사전이 되려면?

{'2': ['a'], '3': ['b'], '1': ['b', 'a']}

10
dict(number_to_letter)
Tim Peters

2
@TimPeters이 질문은 제목이 분명하고 (검색에 쉽게 표시되어야 함) 실제로 잘 작성된 질문이므로 향후 참조를 위해 더 나은 속임수를 찾을 수없는 경우 답변으로 넣을 가치가 있습니다 .. .
Jon Clements

이 답변이 도움이 될 것입니다. stackoverflow.com/a/3031915/1628832
karthikr

1
@JonClements, 좋은 지적하지만, DSM은 이미 한 - 내가 :-) 그의 대답이 허용됩니다 희망
팀 피터스 (Tim Peters)

2
@TimPeters는 10k btw를 축하합니다 ... 오래 걸리지 않을 것 같은 느낌이 들었 습니다. 어느 시점에서 chat.stackoverflow.com/rooms/6/python으로 (부끄러운 플러그) 팝을해야 합니다 :)
Jon Clements

답변:


121

다음과 같이 전화하면됩니다 dict.

>>> a
defaultdict(<type 'list'>, {'1': ['b', 'a'], '3': ['b'], '2': ['a']})
>>> dict(a)
{'1': ['b', 'a'], '3': ['b'], '2': ['a']}

그러나 defaultdict dict 임을 기억하십시오 .

>>> isinstance(a, dict)
True

단지 약간 다른 행동에서 누락되는 키 액세스를 시도 할 때 - 통상을 올릴 것이다 KeyError-가 default_factory대신 호출됩니다

>>> a.default_factory
<type 'list'>

이것이 print a사전의 데이터 측 이 나타나기 전에 볼 수있는 것 입니다.

따라서 실제로 새 객체를 만들지 않고 더 많은 딕셔너리와 같은 동작을 되찾기위한 또 다른 트릭은 재설정하는 것입니다 default_factory.

>>> a.default_factory = None
>>> a[4].append(10)
Traceback (most recent call last):
  File "<ipython-input-6-0721ca19bee1>", line 1, in <module>
    a[4].append(10)
KeyError: 4

그러나 대부분의 경우 이것은 문제의 가치가 없습니다.


저는 파이썬으로 프로그래밍을 배우기 시작했습니다. 사용 방법에 대해 자세히 설명해 주 default_factory시겠습니까? 나는 무슨 일이 일어나고 있는지 전혀 모른다. 죄송합니다.
user2988464

그리고 'KeyError'는 무엇입니까?
user2988464

4
@ user2988464 : 이미 사용했습니다 default_factory- 당신이 만든 때 통과하는 함수의 그 defaultdict것처럼, 처음에 defaultdict(int)defaultdict(list). a['3']예를 들어, 일반적인 사전에서 와 같이 사전에서 키를 찾으려고 할 때마다 값을 얻거나 KeyError예외를 발생시킵니다 (예 : 해당 키를 찾을 수 없음을 알리는 오류). 그러나에 defaultdict, 그것을 대신 호출 default_factory하는 기능을 하게 (즉에서 "기본"의 새 기본 값을 defaultdict당신을 위해 참조).
DSM

2
Django의 .items 템플릿 속성이 defaultdict에서 작동하지 않는다는 점을 알아두면 도움이됩니다. 이것이 제가 여기서 끝낸 이유입니다! 그래서 변환을위한 하나의 좋은 이유있다

2
또한 pickle(python 객체를 파일에 저장하기 위해) 많은 상황defaultdict 에서 s를 처리 할 수 ​​없다는 점을 알아두면 도움이됩니다 .
drevicko

28

예를 들어 defaultdict가 재귀 적으로 정의 된 경우 :

from collections import defaultdict
recurddict = lambda: defaultdict(recurddict)
data = recurddict()
data["hello"] = "world"
data["good"]["day"] = True

defaultdict를 다시 dict로 변환하는 또 다른 간단한 방법은 jsonmodule 을 사용하는 것입니다.

import json
data = json.loads(json.dumps(data))

물론 defaultdict에 포함 된 값은 json 지원 데이터 유형으로 제한되어야하지만 dict에 클래스 나 함수를 저장할 의도가 없다면 문제가되지 않습니다.


8
좋은 생각, 너무 나쁜 데이터는 JSON으로 직렬화되지 않습니다. : * (
Kasapo

15

당신도 재귀를 변환하는 재귀 버전을 원하는 경우 defaultdictA와 dict다음을 시도 할 수 있습니다 :

#! /usr/bin/env python3

from collections import defaultdict

def ddict():
    return defaultdict(ddict)

def ddict2dict(d):
    for k, v in d.items():
        if isinstance(v, dict):
            d[k] = ddict2dict(v)
    return dict(d)

myddict = ddict()

myddict["a"]["b"]["c"] = "value"

print(myddict)

mydict = ddict2dict(myddict)

print(mydict)

그게 바로 내가 필요했던 것입니다! 불행히도, 내 defaultdict에는 커스텀 인코더 없이는 JSON 직렬화 할 수없는 키가 있습니다 (키는 튜플입니다. 내 선택이 아니라 내 문제
일뿐입니다

잘 했어. 사전 이해력을 사용하는 것은 깊이가 2 층 (예 defaultdict(lambda: defaultdict(int)){k: dict(v) for k, v in foo.items()}
:)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.