Eu li os exemplos nos documentos python, mas ainda não consigo descobrir o que esse método significa. Alguém pode ajudar? Aqui estão dois exemplos dos documentos python
>>> from collections import defaultdict
>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
... d[k] += 1
...
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]
e
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
os parâmetros int
e list
são para quê?
python
dictionary
default-value
defaultdict
Lanston
fonte
fonte
default_factory = None
depois de concluir o preenchimento do decreto-padrão. Veja esta pergunta .Respostas:
Normalmente, um dicionário Python lança a
KeyError
se você tentar obter um item com uma chave que não está atualmente no dicionário. Pordefaultdict
outro lado, simplesmente criará quaisquer itens que você tentar acessar (desde que eles ainda não existam). Para criar um item "padrão", ele chama o objeto de função que você passa para o construtor (mais precisamente, é um objeto "solicitável" arbitrário, que inclui objetos de função e tipo). Para o primeiro exemplo, os itens padrão são criados usandoint()
, que retornará o objeto inteiro0
. Para o segundo exemplo, os itens padrão são criados usandolist()
, que retorna um novo objeto de lista vazio.fonte
d.get(key, default)
nunca modificará seu dicionário - ele retornará o padrão e deixará o dicionário inalterado.defaultdict
, por outro lado, inserirá uma chave no dicionário, se ainda não estiver lá. Isso é uma grande diferença; veja os exemplos na pergunta para entender o porquê.defaultdict
chama qualquer construtor que você fornecer. Se você digitar um tipoT
, os valores serão construídos usandoT()
. Nem todos os tipos podem ser construídos sem passar nenhum parâmetro. Se você deseja construir esse tipo, precisa de uma função de wrapper ou algo parecidofunctools.partial(T, arg1, arg2)
.defaultdict
significa que, se uma chave não for encontrada no dicionário, em vez deKeyError
ser lançada, uma nova entrada será criada. O tipo desta nova entrada é fornecido pelo argumento de defaultdict.Por exemplo:
fonte
0
o número inteiro, se fossesomeddict = defaultdict(list)
ele retorna[ ]
. 0 é o número inteiro padrão? Ou [] a lista padrão?0
é imutável - no CPython todos os valores de-5
para256
são singletons em cache, mas esse é um comportamento específico da implementação - em ambos os casos, uma nova instância é "criada" sempre que comint()
oulist()
. Dessa forma,d[k].append(v)
pode funcionar sem preencher o dicionário com referências à mesma lista, o que tornariadefaultdict
quase inútil. Se esse fosse o comportamento,defaultdict
levaria um valor, não um lambda, como parâmetro. (Desculpem a terrível explicação!)defaultdict
"O dicionário padrão inclui o método setdefault () para recuperar um valor e estabelecer um padrão se o valor não existir. Por outro lado,
defaultdict
permite que o chamador especifique o padrão (valor a ser retornado) antecipadamente quando o contêiner é inicializado."conforme definido por Doug Hellmann na The Python Standard Library por exemplo
Como usar o defaultdict
Importar padrão
Inicializar defaultdict
Inicialize passando
ou
Como isso funciona
Como é uma classe filho do dicionário padrão, ele pode executar as mesmas funções.
Mas, no caso de passar uma chave desconhecida, ela retorna o valor padrão em vez de erro. Por exemplo:
Caso você queira alterar o valor padrão, substitua default_factory:
ou
Exemplos na pergunta
Exemplo 1
Como int foi passado como default_factory, qualquer chave desconhecida retornará 0 por padrão.
Agora, como a cadeia é passada no loop, aumentará a contagem desses alfabetos em d.
Exemplo 2
Como uma lista foi passada como default_factory, qualquer chave desconhecida (inexistente) retornará [] (por exemplo, lista) por padrão.
Agora, como a lista de tuplas é passada no loop, ele acrescentará o valor em d [color]
fonte
Os dicionários são uma maneira conveniente de armazenar dados para recuperação posterior por nome (chave). As chaves devem ser objetos únicos e imutáveis e geralmente são cadeias de caracteres. Os valores em um dicionário podem ser qualquer coisa. Para muitas aplicações, os valores são tipos simples, como números inteiros e seqüências de caracteres.
Torna-se mais interessante quando os valores em um dicionário são coleções (listas, dictos etc.) Nesse caso, o valor (uma lista ou dict vazio) deve ser inicializado na primeira vez que uma determinada chave é usada. Embora isso seja relativamente fácil de fazer manualmente, o tipo de comando padrão automatiza e simplifica esses tipos de operações. Um comando padrão funciona exatamente como um comando normal, mas é inicializado com uma função (“fábrica padrão”) que não aceita argumentos e fornece o valor padrão para uma chave inexistente.
Um padrão nunca irá gerar um KeyError. Qualquer chave que não existe obtém o valor retornado pela fábrica padrão.
Aqui está outro exemplo de como usar o defaultdict, podemos reduzir a complexidade
Concluindo, sempre que você precisar de um dicionário e o valor de cada elemento começar com um valor padrão, use um padrão.
fonte
Há uma ótima explicação para os defaultdicts aqui: http://ludovf.net/blog/python-collections-defaultdict/
Basicamente, os parâmetros int e list são funções que você passa. Lembre-se de que o Python aceita nomes de funções como argumentos. int retorna 0 por padrão e list retorna uma lista vazia quando chamada entre parênteses.
Nos dicionários normais, se no seu exemplo eu tentar chamar
d[a]
, receberei um erro (KeyError), pois apenas existem as chaves m, s, ie ep e a chave a não foi inicializada. Mas em um padrão, ele assume o nome de uma função como argumento, quando você tenta usar uma chave que não foi inicializada, simplesmente chama a função que você passou e atribui seu valor de retorno como o valor da nova chave.fonte
Como a pergunta é sobre "como funciona", alguns leitores podem querer ver mais porcas e parafusos. Especificamente, o método em questão é o
__missing__(key)
método. Consulte: https://docs.python.org/2/library/collections.html#defaultdict-objects .Mais concretamente, esta resposta mostra como fazer uso de
__missing__(key)
uma maneira prática: https://stackoverflow.com/a/17956989/1593924Para esclarecer o que significa 'chamar', aqui está uma sessão interativa (da 2.7.6, mas também deve funcionar na v3):
Esse foi o uso mais típico do defaultdict (exceto o uso inútil da variável x). Você pode fazer o mesmo com 0 como o valor padrão explícito, mas não com um valor simples:
Em vez disso, o seguinte funciona porque passa em uma função simples (cria instantaneamente uma função sem nome que não aceita argumentos e sempre retorna 0):
E com um valor padrão diferente:
fonte
Meus 2 ¢: você também pode subclass defaultdict:
Isso pode ser útil para casos muito complexos.
fonte
O comportamento de
defaultdict
pode ser facilmente imitado usando emdict.setdefault
vez ded[key]
em todas as chamadas.Em outras palavras, o código:
é equivalente a:
A única diferença é que, usando
defaultdict
, o construtor da lista é chamado apenas uma vez e o usodict.setdefault
do construtor da lista é chamado com mais frequência (mas o código pode ser reescrito para evitar isso, se realmente necessário).Alguns podem argumentar que há uma consideração de desempenho, mas esse tópico é um campo minado. Esta postagem mostra que não há um grande ganho de desempenho no uso do defaultdict, por exemplo.
IMO, defaultdict é uma coleção que adiciona mais confusão do que benefícios ao código. Inútil para mim, mas outros podem pensar diferente.
fonte
A ferramenta defaultdict é um contêiner na classe de coleções do Python. É semelhante ao contêiner usual do dicionário (dict), mas tem uma diferença: o tipo de dados dos campos de valor é especificado na inicialização.
Por exemplo:
Isso imprime:
fonte
list
está a função a ser chamada para preencher um valor ausente, não o tipo dos objetos a serem criados. Por exemplo, para ter um valor padrão de1
, você usaria olambda:1
que obviamente não é um tipo.Eu acho que é melhor usado no lugar de uma declaração de caso de switch. Imagine se tivermos uma declaração de caso de mudança como abaixo:
Não há
switch
instruções de caso disponíveis em python. Podemos conseguir o mesmo usandodefaultdict
.Imprime:
No trecho acima
dd
, não há chaves 4 ou 5 e, portanto, imprime um valor padrão que configuramos em uma função auxiliar. Isso é muito melhor do que um dicionário bruto, onde aKeyError
é lançada se a chave não estiver presente. A partir disso, é evidente quedefaultdict
mais se parece com uma declaração de caso de mudança em que podemos evitarif-elif-elif-else
blocos complicados .Mais um bom exemplo que me impressionou muito neste site é:
Se tentarmos acessar outros itens que não sejam
eggs
espam
obteremos uma contagem de 0.fonte
Sem
defaultdict
, você provavelmente pode atribuir novos valores a chaves invisíveis, mas não pode modificá-lo. Por exemplo:fonte
Bem, o defaultdict também pode gerar keyerror no seguinte caso:
Lembre-se sempre de fornecer argumentos para o defaultdict como defaultdict (int).
fonte
O dicionário padrão inclui o método setdefault () para recuperar um valor e estabelecer um padrão se o valor não existir. Por outro lado, defaultdict permite que o chamador especifique o padrão antecipadamente quando o contêiner é inicializado.
Isso funciona bem desde que seja apropriado que todas as chaves tenham o mesmo padrão. Pode ser especialmente útil se o padrão for um tipo usado para agregar ou acumular valores, como uma lista, conjunto ou mesmo int. A documentação da biblioteca padrão inclui vários exemplos de uso do defaultdict dessa maneira.
fonte
Em resumo:
defaultdict(int)
- o argumento int indica que os valores serão do tipo int.defaultdict(list)
- a lista de argumentos indica que os valores serão do tipo lista.fonte
A documentação e a explicação são praticamente auto-explicativas:
http://docs.python.org/library/collections.html#collections.defaultdict
A função type (int / str etc.) passada como argumento é usada para inicializar um valor padrão para qualquer chave em que a chave não está presente no dict.
fonte