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 aaparece 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 defaultdictem 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 KeyErrorexceção (como um erro, informando que não foi possível encontrar aquela chave). Mas em um defaultdict, ele chama a default_factoryfunçã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 defaultdicts 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 jsonmó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 defaultdictem um, dictpode 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)