Por exemplo, eu tenho dois ditados:
Dict A: {'a': 1, 'b': 2, 'c': 3}
Dict B: {'b': 3, 'c': 4, 'd': 5}
Eu preciso de uma maneira pitônica de 'combinar' dois ditados, para que o resultado seja:
{'a': 1, 'b': 5, 'c': 7, 'd': 5}
Ou seja: se uma chave aparecer em ambos os ditados, adicione seus valores; se aparecer em apenas um ditado, mantenha seu valor.
python
dictionary
Derrick Zhang
fonte
fonte
sum(counters)
infelizmente não funciona.sum()
um valor inicial, comsum(counters, Counter())
.+=
fazer a soma no local.res = counters[0]
entãofor c in counters[1:]: res += c
.update()
em vez de+=
:for c in counters[1:]: res.update(c)
.Uma solução mais genérica, que também funciona para valores não numéricos:
ou ainda mais genérico:
Por exemplo:
fonte
for k in b.viewkeys() & a.viewkeys()
, ao usar python 2.7 , e pular a criação de conjuntos.set(a)
retornar o conjunto de chaves em vez do conjunto de tuplas? Qual é a justificativa para isso?list({..})
,for k in {...}
etcoperator.mul
claro que esse código é genérico e não se limita a adicionar números.{**a, **b, **{k: op(a[k], b[k]) for k in a.keys() & b}}
deve funcionar em Python 3.5+.fonte
for x in set(itertools.chain(A, B))
seria mais lógico? Como usar set on dict é um absurdo, já que as chaves já são únicas? Eu sei que é apenas outra maneira de obter um conjunto de chaves, mas acho que é mais confuso do que usaritertools.chain
(o que implica que você sabe o queitertools.chain
faz)Introdução: Existem as (provavelmente) melhores soluções. Mas você precisa conhecê-lo e lembrá-lo e, às vezes, espera que sua versão do Python não seja muito antiga ou seja qual for o problema.
Depois, há as soluções mais 'hacky'. Eles são ótimos e curtos, mas às vezes são difíceis de entender, ler e lembrar.
Existe, no entanto, uma alternativa que é tentar reinventar a roda. - Por que reinventar a roda? - Geralmente porque é uma maneira muito boa de aprender (e às vezes apenas porque a ferramenta já existente não faz exatamente o que você gostaria e / ou da maneira que você gostaria) e a maneira mais fácil se você não conhece ou não lembre-se da ferramenta perfeita para o seu problema.
Então , proponho reinventar a roda da
Counter
classe a partir docollections
módulo (pelo menos parcialmente):Provavelmente haveria outras maneiras de implementar isso e já existem ferramentas para fazer isso, mas é sempre bom visualizar como as coisas funcionariam basicamente.
fonte
fonte
Aquele sem importações extras!
É um padrão pitônico chamado EAFP (mais fácil pedir perdão do que permissão). O código abaixo é baseado nesse padrão python .
EDIT: obrigado a Jerzyk por suas sugestões de melhoria.
fonte
Definitivamente, somar os
Counter()
s é a maneira mais pitônica de seguir nesses casos, mas apenas se resultar em um valor positivo . Aqui está um exemplo e, como você pode ver, não hác
resultado após negar oc
valor doB
dicionário.Isso
Counter
ocorre porque s foram projetados principalmente para trabalhar com números inteiros positivos para representar contagens em execução (contagem negativa não faz sentido). Mas, para ajudar nesses casos de uso, o python documenta as restrições mínimas de alcance e tipo da seguinte maneira:Portanto, para contornar esse problema depois de somar seu contador, você pode usar
Counter.update
-lo para obter a saída desejada. Funciona como,dict.update()
mas adiciona contagens, em vez de substituí-las.fonte
OU
Alternativa, você pode usar o Counter como o @Martijn mencionou acima.
fonte
Para uma maneira mais genérica e extensível, verifique mesclagem . Usa
singledispatch
e pode mesclar valores com base em seus tipos.Exemplo:
fonte
Do python 3.5: mesclando e somando
Graças a @tokeinizer_fsj que me disse em um comentário que eu não entendi completamente o significado da pergunta (eu pensei que adicionar significava apenas adicionar chaves que eventualmente eram diferentes nos dois dicionários) e, em vez disso, eu quis dizer que os valores de chave comum deve ser resumido). Então, eu adicionei esse loop antes da mesclagem, para que o segundo dicionário contenha a soma das chaves comuns. O último dicionário será aquele cujos valores durarão no novo dicionário que é o resultado da fusão dos dois, então eu acho que o problema está resolvido. A solução é válida no python 3.5 e nas seguintes versões.
Código reutilizável
fonte
b
é5
(2 + 3), mas seu método está retornando3
.Além disso, observe que
a.update( b )
é 2x mais rápido quea + b
fonte
Você pode facilmente generalizar isso:
Então pode levar qualquer número de ditados.
fonte
Esta é uma solução simples para mesclar dois dicionários, onde
+=
pode ser aplicada aos valores; ela precisa repetir o dicionário apenas uma vez.fonte
Esta solução é fácil de usar, é usada como um dicionário normal, mas você pode usar a função soma.
fonte
A respeito:
Resultado:
fonte
As soluções acima são ótimas para o cenário em que você possui um pequeno número de
Counter
s. Se você tem uma grande lista deles, algo assim é muito melhor:A solução acima está basicamente somando os
Counter
s por:Isso faz a mesma coisa, mas acho que sempre ajuda a ver o que está efetivamente fazendo por baixo.
fonte
Mesclando três ditados a, b, c em uma única linha sem outros módulos ou bibliotecas
Se temos os três ditados
Mesclar tudo com uma única linha e retornar um objeto dict usando
Retornando
fonte
{'a': 9, 'b': 9, 'd': 90}
. Está faltando o requisito "soma".