Есть ли лучший способ сравнить значения словаря
В настоящее время я использую следующую функцию для сравнения значений словаря. Есть ли более быстрый или лучший способ сделать это?
match = True
for keys in dict1:
if dict1[keys] != dict2[keys]:
match = False
print keys
print dict1[keys],
print '->' ,
print dict2[keys]
Изменить: Оба файла содержат одни и те же клавиши.
Ответы
Ответ 1
Если у dicts есть одинаковые наборы ключей, и вам нужны все эти отпечатки для любой разницы в стоимости, вы не можете многое сделать; может быть что-то вроде:
diffkeys = [k for k in dict1 if dict1[k] != dict2[k]]
for k in diffkeys:
print k, ':', dict1[k], '->', dict2[k]
в значительной степени эквивалентен тому, что у вас есть, но вы можете получить более приятную презентацию, например, путем сортировки diffkeys перед тем, как вы на ней нажмете.
Ответ 2
Если истинным намерением вопроса является сравнение между dicts (а не печать различий), ответ
dict1 == dict2
Это уже упоминалось ранее, но я чувствовал, что он немного утонул в других битах информации. Это может показаться поверхностным, но сравнение значений dicts имеет действительно сильную семантику. Он охватывает
- количество ключей (если они не совпадают, dicts не равны)
- имена ключей (если они не совпадают, они не равны)
- значение каждой клавиши (они также должны быть "==" )
Последняя точка снова кажется тривиальной, но интересна, так как это означает, что все это применяется рекурсивно к вложенным dicts. Например.
m1 = {'f':True}
m2 = {'f':True}
m3 = {'a':1, 2:2, 3:m1}
m4 = {'a':1, 2:2, 3:m2}
m3 == m4 # True
Аналогичная семантика существует для сравнения списков. Все это делает его неинтересным, например, сравните глубокие структуры Json, только с простым "==".
Ответ 3
Вы также можете использовать наборы для этого
>>> a = {'x': 1, 'y': 2}
>>> b = {'y': 2, 'x': 1}
>>> set(a.iteritems())-set(b.iteritems())
set([])
>>> a['y']=3
>>> set(a.iteritems())-set(b.iteritems())
set([('y', 3)])
>>> set(b.iteritems())-set(a.iteritems())
set([('y', 2)])
>>> set(b.iteritems())^set(a.iteritems())
set([('y', 3), ('y', 2)])
Ответ 4
Uhm, вы описываете dict1 == dict2
(проверьте, равны ли оба dicts)
Но что делает ваш код, это all( dict1[k]==dict2[k] for k in dict1 )
(проверьте, равны ли все записи в dict1 в dict2)
Ответ 5
Не уверен, что это помогает, но в моем приложении мне пришлось проверить, изменился ли словарь.
Выполнение этого не будет работать, поскольку в принципе это все тот же объект:
val={'A':1,'B':2}
old_val=val
val['A']=10
if old_val != val:
print('changed')
Использование операций копирования/глубокой печати:
import copy
val={'A':1,'B':2}
old_val=copy.deepcopy(val)
val['A']=10
if old_val != val:
print('changed')
Ответ 6
Если вы просто сравниваете для равенства, вы можете просто сделать это:
if not dict1 == dict2:
match = False
В противном случае единственная серьезная проблема, которую я вижу, заключается в том, что вы получите KeyError, если есть ключ в dict1, который не находится в dict2, поэтому вы можете сделать что-то вроде этого:
for key in dict1:
if not key in dict2 or dict1[key] != dict2[key]:
match = False
Вы можете сжать это в понимание, чтобы просто получить список ключей, которые тоже не совпадают:
mismatch_keys = [key for key in x if not key in y or x[key] != y[key]]
match = not bool(mismatch_keys) #If the list is not empty, they don't match
for key in mismatch_keys:
print key
print '%s -> %s' % (dict1[key],dict2[key])
Единственная другая оптимизация, о которой я могу думать, может состоять в том, чтобы использовать "len (dict)", чтобы выяснить, какой dict имеет меньше записей и прокручивает этот первый, чтобы получить самый короткий цикл.
Ответ 7
>>> a = {'x': 1, 'y': 2}
>>> b = {'y': 2, 'x': 1}
>>> print a == b
True
>>> c = {'z': 1}
>>> print a == c
False
>>>
Ответ 8
Если ваши словари глубоко вложены, и если они содержат разные типы коллекций, вы можете преобразовать их в строку json и сравнить.
import json
match = (json.dumps(dict1) == json.dumps(dict2))
caveat- это решение может не работать, если ваши словари имеют двоичные строки в значениях, поскольку это не сериализуемое json