Eu tenho dois dicionários, mas, para simplificação, vou usar estes dois:
>>> x = dict(a=1, b=2)
>>> y = dict(a=2, b=2)
Agora, quero comparar se cada key, value
par x
tem o mesmo valor correspondente em y
. Então eu escrevi isso:
>>> for x_values, y_values in zip(x.iteritems(), y.iteritems()):
if x_values == y_values:
print 'Ok', x_values, y_values
else:
print 'Not', x_values, y_values
E funciona desde que a tuple
é retornado e depois comparado para igualdade.
Minhas perguntas:
Isso está correto? Existe uma maneira melhor de fazer isso? Melhor não em velocidade, estou falando sobre elegância de código.
UPDATE: Esqueci de mencionar que tenho que verificar quantos key, value
pares são iguais.
python
dictionary
comparison
user225312
fonte
fonte
x == y
deve ser verdade de acordo com stackoverflow.com/a/5635309/186202Respostas:
Se você quiser saber quantos valores correspondem nos dois dicionários, deveria ter dito isso :)
Talvez algo parecido com isto:
fonte
list
chave em primeiro lugar.x = {[1,2]: 2}
vai falhar. A pergunta já tem validadedicts
.list
chaves não é um código python válido - as chaves do dict devem ser imutáveis. Portanto, você não está comparando dicionários. Se você tentar usar uma lista como uma chave de dicionário, seu código não será executado. Você não tem objetos para os quais comparar. É como digitarx = dict(23\;dfg&^*$^%$^$%^)
e reclamar como a comparação não funciona com o dicionário. Claro que não vai funcionar. O comentário de Tim, por outro lado, é sobre mutávelvalues
, por isso eu disse que essas são questões diferentes.set
exige que os valores sejam laváveis edict
que as chaves sejam laváveis.set(x.keys())
sempre funcionará porque as chaves precisam ser laváveis, masset(x.values())
falharão em valores que não são laváveis.O que você quer fazer é simplesmente
x==y
O que você faz não é uma boa ideia, porque os itens de um dicionário não devem ter nenhum pedido. Você pode estar comparando
[('a',1),('b',1)]
com[('b',1), ('a',1)]
(mesmos dicionários, ordem diferente).Por exemplo, veja isto:
A diferença é de apenas um item, mas seu algoritmo verá que todos os itens são diferentes
fonte
fonte
DataFrame
s por design não permite comparações verdadeiras (a menos que tenha um comprimento de 1), pois elas são herdadasnumpy.ndarray
. -credit para stackoverflow.com/a/33307396/994076dic1 == dic2
Dos documentos python :
Válido para ambos
py2
epy3
.fonte
OrderedDict != dict
Eu sou novo em python, mas acabei fazendo algo semelhante ao @mouad
O operador XOR (
^
) deve eliminar todos os elementos do ditado quando forem iguais nos dois ditados.fonte
{'a':{'b':1}}
dáTypeError: unhashable type: 'dict'
)Como parece que ninguém mencionou
deepdiff
, vou adicioná-lo aqui para completar. Eu acho muito conveniente para obter diff de objetos (aninhados) em geral:Instalação
Código de amostra
Resultado
Nota sobre a impressão bonita do resultado para inspeção: O código acima funciona se ambos os dictos tiverem as mesmas chaves de atributo (com valores de atributo possivelmente diferentes, como no exemplo). No entanto, se um
"extra"
atributo estiver presente é um dos dictos,json.dumps()
falhará comSolução: use
diff.to_json()
ejson.loads()
/json.dumps()
para imprimir bem:Resultado:
Alternativa: use
pprint
, resulta em uma formatação diferente:Resultado:
fonte
Apenas use:
fonte
dict1 == dict2
cmp
construído em foi removida (e devem ser tratados como removido antes Uma alternativa eles propõem:.(a > b) - (a < b) == cmp(a, b)
Por um seu equivalente funcional (ou melhor__eq__
e__hash__
)TypeError
::unorderable types: dict() < dict()
A resposta de @mouad é boa se você assumir que ambos os dicionários contêm apenas valores simples. No entanto, se você tiver dicionários que contenham dicionários, você receberá uma exceção, pois os dicionários não são hasháveis.
Em cima da minha cabeça, algo como isto pode funcionar:
fonte
not isinstance(dict1, dict)
vez detype(dict1) is not dict
, isso funcionará em outras classes baseadas emdict. Also, instead of
(dict1 [chave] == dict2 [chave]), you can do
todas (atleast_1d (dict1 [chave] == dict2 [chave])) `para manipular matrizes pelo menos.for loop
assim quedicts_are_equal
se tornar falso. Não há necessidade de continuar mais.Outra possibilidade, até a última nota do OP, é comparar os hashes (
SHA
ouMD
) dos dictos despejados como JSON. A maneira como os hashes são construídos garante que, se forem iguais, as cadeias de origem também sejam iguais. Isso é muito rápido e matematicamente correto.fonte
json.dumps(d, sort_keys=True)
fornecerá JSON canônico para que você possa ter certeza de que os dois dict são equivalentes. Também depende do que você está tentando obter. Assim que o valor não for JSON serizalizable, ele falhará. Para quem diz que é ineficiente, dê uma olhada no projeto ujson.A função é fina IMO, clara e intuitiva. Mas apenas para lhe dar (outra) resposta, aqui está a minha chance:
Pode ser útil para você ou para qualquer outra pessoa.
EDITAR:
Eu criei uma versão recursiva da acima. Não vi isso nas outras respostas
fonte
Para testar se dois ditados são iguais em chaves e valores:
Se você deseja retornar os valores que diferem, escreva-o de forma diferente:
Você teria que chamá-lo duas vezes, ou seja
fonte
Código
Teste
fonte
Uma simples comparação com == deve ser suficiente atualmente (python 3.8). Mesmo quando você compara os mesmos ditados em uma ordem diferente (último exemplo). O melhor é que você não precisa de um pacote de terceiros para fazer isso.
fonte
Chegar atrasado na minha resposta é melhor do que nunca!
Comparar Not_Equal é mais eficiente do que comparar Igual. Como tais dois ditados não são iguais se nenhum valor-chave em um ditado não for encontrado no outro ditado. O código abaixo leva em consideração que você talvez esteja comparando o dict padrão e, portanto, usa get em vez de getitem [].
Usar um tipo de valor aleatório como padrão na chamada get igual à chave que está sendo recuperada - apenas no caso de os dictos terem um None como valor em um dict e essa chave não existir no outro. Além disso, a condição get! = É verificada antes da condição não em termos de eficiência, porque você está verificando as chaves e os valores de ambos os lados ao mesmo tempo.
fonte
Estou usando esta solução que funciona perfeitamente para mim no Python 3
Ele compara dict, list e quaisquer outros tipos que implementem o operador "==" sozinhos. Se você precisar comparar algo diferente, adicione um novo ramo na "se árvore".
Espero que ajude.
fonte
para python3:
fonte
Aqui está outra opção:
Então, como você vê, os dois IDs são diferentes. Mas os ricos operadores de comparação parecem fazer o truque:
fonte
No PyUnit, existe um método que compara dicionários lindamente. Testei-o usando os dois dicionários a seguir e ele faz exatamente o que você está procurando.
Não recomendo importar
unittest
para o seu código de produção. Meu pensamento é que a fonte no PyUnit poderia ser reutilizada para executar na produção. Ele usapprint
"impressões bonitas" nos dicionários. Parece muito fácil adaptar esse código para estar "pronto para produção".fonte
consulte o dicionário para ver objetos: https://docs.python.org/2/library/stdtypes.html#dict
Dessa forma, você pode subtrair o dictView2 do dictView1 e ele retornará um conjunto de pares de chave / valor diferentes no dictView2:
Você pode interceptar, união, diferença (mostrada acima), diferença simétrica esses objetos de exibição de dicionário.
Melhor? Mais rápido? - não tenho certeza, mas parte da biblioteca padrão - o que torna uma grande vantagem para a portabilidade
fonte
O código abaixo o ajudará a comparar a lista de dict em python
fonte
fonte
No Python 3.6, isso pode ser feito como: -
A variável ret será verdadeira se todos os itens de dict_1 presentes no dict_2
fonte
Aqui está a minha resposta, use uma maneira recursize:
Espero que ajude!
fonte
Por que não apenas percorrer um dicionário e verificar o outro no processo (assumindo que os dois dicionários tenham as mesmas chaves)?
Resultado:
fonte
fonte
json.dumps
é determinístico nas configurações padrão).