Graças a ótimas pessoas no SO, descobri as possibilidades oferecidas por collections.defaultdict
, principalmente em legibilidade e velocidade. Eu os coloquei para uso com sucesso.
Agora eu gostaria de implementar três níveis de dicionários, sendo os dois principais defaultdict
e o mais baixo int
. Não encontro a maneira apropriada de fazer isso. Aqui está a minha tentativa:
from collections import defaultdict
d = defaultdict(defaultdict)
a = [("key1", {"a1":22, "a2":33}),
("key2", {"a1":32, "a2":55}),
("key3", {"a1":43, "a2":44})]
for i in a:
d[i[0]] = i[1]
Agora isso funciona, mas o seguinte, que é o comportamento desejado, não funciona:
d["key4"]["a1"] + 1
Suspeito que deveria ter declarado em algum lugar que o segundo nível defaultdict
é do tipo int
, mas não encontrei onde ou como fazê-lo.
A razão pela qual estou usando defaultdict
em primeiro lugar é evitar ter que inicializar o dicionário para cada nova chave.
Alguma sugestão mais elegante?
Obrigado pythoneers!
fonte
multiprocessing
é infeliz em enviá-las para frente e para trás.d[new_key]
é acessado, ele chama o lambda que criará um novodefaultdict(int)
. E quandod[existing_key][new_key2]
for acessado, um novoint
será criado.multiprocessing
e o que é uma função no nível do módulo nomeado? Esta pergunta segue.Outra maneira de criar um padrão padrão aninhado e selecionável é usar um objeto parcial em vez de um lambda:
Isso funcionará porque a classe defaultdict é acessível globalmente no nível do módulo:
fonte
Olhe para a resposta de nosklo aqui para uma solução mais geral.
Teste:
Resultado:
fonte
Conforme a solicitação de @ rschwieb
D['key'] += 1
, podemos expandir o anterior substituindo a adição pela definição do__add__
método, para fazer com que ele se comporte mais como umcollections.Counter()
Primeiro
__missing__
será chamado para criar um novo valor vazio, que será passado para__add__
. Testamos o valor, contando com valores vazios a seremFalse
.Consulte emulando tipos numéricos para obter mais informações sobre substituição.
Exemplos:
Em vez de verificar o argumento é um número (muito não-python, amirite!), Poderíamos apenas fornecer um valor 0 padrão e, em seguida, tentar a operação:
fonte
Tarde para a festa, mas por profundidade arbitrária eu acabei de fazer algo assim:
O truque aqui é basicamente tornar a
DeepDict
instância em si uma fábrica válida para a construção de valores ausentes. Agora podemos fazer coisas comofonte
Sem erros novamente. Não importa quantos níveis estejam aninhados. pop nenhum erro também
dd = DefaultDict ({"1": 333333})
fonte