У меня есть два словаря, но для упрощения я возьму эти два:
>>> x = dict(a=1, b=2)
>>> y = dict(a=2, b=2)
Теперь я хочу сравнить, имеет ли каждая key, value
пара x
одинаковое значение в y
. Итак, я написал это:
>>> 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
И это работает, так как tuple
возвращается и сравнивается на равенство.
Мои вопросы:
Это верно? Есть ли лучший способ сделать это? Лучше не в скорости, я говорю об элегантности кода.
ОБНОВЛЕНИЕ: я забыл упомянуть, что я должен проверить, сколько key, value
пар равны.
python
dictionary
comparison
user225312
источник
источник
x == y
должно быть верно в соответствии со stackoverflow.com/a/5635309/186202Ответы:
Если вы хотите узнать, сколько значений совпадают в обоих словарях, вы должны были это сказать :)
Может быть, что-то вроде этого:
источник
list
ключом в первую очередь.x = {[1,2]: 2}
не удастся. Вопрос уже имеет действительныйdicts
.list
ключами не является допустимым кодом Python - ключи dict должны быть неизменными. Поэтому вы не сравниваете словари. Если вы попытаетесь использовать список в качестве словарного ключа, ваш код не запустится. У вас нет объектов для сравнения. Это все равно что печатать, аx = dict(23\;dfg&^*$^%$^$%^)
потом жаловаться, что сравнение не работает со словарем. Конечно, это не сработает. Комментарий Тима с другой стороны касается изменчивостиvalues
, поэтому я и сказал, что это разные вопросы.set
требует, чтобы значения были хэшируемыми, аdict
ключи - хэшируемыми.set(x.keys())
всегда будет работать, потому что ключи должны быть хэшируемыми, но неset(x.values())
будут работать со значениями, которые не хэшируются.То, что вы хотите сделать, это просто
x==y
То, что вы делаете, не очень хорошая идея, потому что элементы в словаре не должны иметь никакого порядка. Возможно, вы сравниваете
[('a',1),('b',1)]
с[('b',1), ('a',1)]
(одни и те же словари, другой порядок).Например, посмотрите это:
Разница только в одном предмете, но ваш алгоритм увидит, что все предметы разные
источник
источник
DataFrame
по своему замыслу не допускает достоверных сравнений (если они не имеют длину 1), поскольку они наследуютсяnumpy.ndarray
. -credit to stackoverflow.com/a/33307396/994076dic1 == dic2
Из документов Python :
Действительно для обоих
py2
иpy3
.источник
OrderedDict != dict
Поскольку, кажется, никто не упомянул
deepdiff
, я добавлю это здесь для полноты. Я нахожу это очень удобным для получения различий (вложенных) объектов в целом:Монтаж
Образец кода
Вывод
Примечание о приятной распечатке результата для проверки: приведенный выше код работает, если оба слова имеют одинаковые ключи атрибутов (возможно, с разными значениями атрибутов, как в примере). Тем не менее, если
"extra"
атрибут присутствует является одним из диктов, происходитjson.dumps()
сбой сРешение: используйте
diff.to_json()
andjson.loads()
/json.dumps()
to pretty-print:Вывод:
Альтернатива: использование
pprint
, результаты в другом формате:Вывод:
источник
Я новичок в Python, но в итоге я сделал что-то похожее на @mouad
Оператор XOR (
^
) должен удалять все элементы dict, если они одинаковы в обоих dict.источник
{'a':{'b':1}}
даетTypeError: unhashable type: 'dict'
)Просто используйте:
источник
dict1 == dict2
cmp
встроенное было удалено (и должно рассматриваться как удаленное ранее . Альтернатива, которую они предлагают:(a > b) - (a < b) == cmp(a, b)
для функционального эквивалента (или лучше__eq__
и__hash__
)TypeError
:unorderable types: dict() < dict()
Ответ @mouad хорош, если вы предполагаете, что оба словаря содержат только простые значения. Однако, если у вас есть словари, которые содержат словари, вы получите исключение, так как словари не являются хэшируемыми.
Вне моей головы, что-то вроде этого может работать:
источник
not isinstance(dict1, dict)
вместо этогоtype(dict1) is not dict
, это будет работать с другими классами на основеdict. Also, instead of
(dict1 [ключ] == dict2 [ключ]), you can do
всех (atleast_1d (dict1 [ключ] == dict2 [ключ])) `для обработки массивов, по крайней мере.for loop
как только вашdicts_are_equal
станет ложным. Там нет необходимости продолжать дальше.Еще одна возможность, вплоть до последней ноты OP, состоит в том, чтобы сравнивать хэши (
SHA
илиMD
) диктов, сброшенных как JSON. Способ создания хэшей гарантирует, что, если они равны, исходные строки также равны. Это очень быстро и математически правильно.источник
json.dumps(d, sort_keys=True)
даст вам канонический JSON, так что вы можете быть уверены, что оба dict эквивалентны. Также это зависит от того, чего вы пытаетесь достичь. Как только значение не будет сериализуемым в формате JSON, произойдет сбой. Для тех, кто говорит, что это неэффективно, взгляните на проект ujson.Функция отлично IMO, понятная и интуитивно понятная. Но просто чтобы дать вам (еще один) ответ, вот мой путь:
Может быть полезным для вас или для кого-либо еще ..
РЕДАКТИРОВАТЬ:
Я создал рекурсивную версию вышеупомянутой .. Не видел, что в других ответах
источник
Чтобы проверить, равны ли два ключа по ключам и значениям:
Если вы хотите вернуть значения, которые отличаются, напишите это по-другому:
Вы должны были бы назвать это дважды, т.е.
источник
Код
Тест
источник
Простого сравнения с == сегодня должно быть достаточно (python 3.8). Даже когда вы сравниваете одни и те же слова в другом порядке (последний пример). Лучше всего, вам не нужен сторонний пакет для этого.
источник
Опоздание в моем ответе лучше, чем никогда!
Сравнение Not_Equal более эффективно, чем сравнение Equal. Таким образом, два диктата не равны, если какие-либо ключевые значения в одном из них не найдены в другом. Приведенный ниже код учитывает, что вы, возможно, сравниваете dict по умолчанию и, следовательно, используете get вместо getitem [].
Использование своего рода случайного значения в качестве значения по умолчанию при вызове get, равного ключу, который нужно получить, - только в том случае, если для dicts значение None установлено в одном dict, а этот ключ не существует в другом. Кроме того, условие get! = Проверяется перед условием не в состоянии для эффективности, потому что вы выполняете проверку ключей и значений с обеих сторон одновременно.
источник
Я использую это решение, которое отлично работает для меня в Python 3
Он сравнивает dict, list и любые другие типы, которые сами реализуют оператор "==". Если вам нужно сравнить что-то другое, вам нужно добавить новую ветку в «если дерево».
Надеюсь, это поможет.
источник
для python3:
источник
Вот еще один вариант:
Итак, как вы видите, два идентификатора разные. Но богатые операторы сравнения, кажется, делают свое дело:
источник
В PyUnit есть метод, который прекрасно сравнивает словари. Я протестировал его, используя следующие два словаря, и он делает именно то, что вы ищете.
Я не рекомендую импортировать
unittest
в ваш производственный код. Я думаю, что источник в PyUnit может быть изменен для запуска в производство. Используетpprint
какие "красивые печатает" словари. Кажется довольно легко адаптировать этот код, чтобы он был «готов к работе».источник
см. объекты представления словаря: https://docs.python.org/2/library/stdtypes.html#dict
Таким образом, вы можете вычесть dictView2 из dictView1, и он вернет набор пар ключ / значение, которые отличаются в dictView2:
Вы можете пересекать, объединять, различать (показано выше), симметричную разность этих объектов представления словаря.
Лучше? Быстрее? - не уверен, но часть стандартной библиотеки - что делает его большим плюсом для мобильности
источник
Ниже код поможет вам сравнить список dict в Python
источник
источник
В Python 3.6 это можно сделать так:
переменная ret будет true, если все элементы dict_1 присутствуют в dict_2
источник
Вот мой ответ, используйте рекурсивный способ:
Надеюсь, это поможет!
источник
Почему бы просто не перебрать один словарь и проверить другой в процессе (при условии, что оба словаря имеют одинаковые ключи)?
Вывод:
источник
Самый простой способ (и один из самых надежных) для глубокого сравнения двух словарей состоит в их сериализации в формате JSON, сортировке ключей и сравнении строковых результатов:
источник
источник
json.dumps
является детерминированным с настройками по умолчанию).