Como posso converter um defaultdict
number_to_letter
defaultdict(<class 'list'>, {'2': ['a'], '3': ['b'], '1': ['b', 'a']})
para ser um ditado comum?
{'2': ['a'], '3': ['b'], '1': ['b', 'a']}
Como posso converter um defaultdict
number_to_letter
defaultdict(<class 'list'>, {'2': ['a'], '3': ['b'], '1': ['b', 'a']})
para ser um ditado comum?
{'2': ['a'], '3': ['b'], '1': ['b', 'a']}
Respostas:
Você pode simplesmente ligar para dict
:
>>> a
defaultdict(<type 'list'>, {'1': ['b', 'a'], '3': ['b'], '2': ['a']})
>>> dict(a)
{'1': ['b', 'a'], '3': ['b'], '2': ['a']}
mas lembre-se de que um defaultdict é um dict:
>>> isinstance(a, dict)
True
apenas com um comportamento ligeiramente diferente, em que quando você tenta acessar uma chave que está faltando - o que normalmente geraria um KeyError
- o default_factory
é chamado em vez disso:
>>> a.default_factory
<type 'list'>
É isso que você vê quando print a
aparece antes do lado dos dados do dicionário.
Portanto, outro truque para obter de volta um comportamento mais semelhante ao de um ditado, sem realmente fazer um novo objeto, é redefinir 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
mas na maioria das vezes isso não vale a pena.
default_factory
? Eu simplesmente não tenho ideia do que está acontecendo. Desculpa.
default_factory
- essa é a função que você passou quando fez o defaultdict
em primeiro lugar, como defaultdict(int)
ou defaultdict(list)
. Sempre que você tenta procurar uma chave no dicionário, como a['3']
, por exemplo, em um dicionário comum, você obtém o valor ou gera uma KeyError
exceção (como um erro, informando que não foi possível encontrar aquela chave). Mas em um defaultdict
, ele chama a default_factory
função para criar um novo valor padrão (que é o "padrão" em defaultdict
) para você.
pickle
(para salvar objetos Python em um arquivo) não pode lidar com defaultdict
s em muitas circunstâncias .
Se o seu defaultdict for definido recursivamente, por exemplo:
from collections import defaultdict
recurddict = lambda: defaultdict(recurddict)
data = recurddict()
data["hello"] = "world"
data["good"]["day"] = True
ainda outra maneira simples de converter defaultdict de volta em dict é usar o json
módulo
import json
data = json.loads(json.dumps(data))
e, claro, os valores contidos em seu defaultdict precisam ser confinados aos tipos de dados suportados por json, mas não deve ser um problema se você não tem a intenção de armazenar classes ou funções no dicionário.
Se você deseja uma versão recursiva para converter um recursivo defaultdict
em um, dict
pode tentar o seguinte:
#! /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(lambda: defaultdict(int))
): {k: dict(v) for k, v in foo.items()}
dict(number_to_letter)