Python - сравнение двух двумерных диктов - PullRequest
0 голосов
/ 03 мая 2018

Попытка сравнить 2 двумерных диктанта в Python

Написал этот код:

import collections
import json
import pprint

def dict_compare(d1, d2):
    d1_keys = set(d1.keys())
    d2_keys = set(d2.keys())
    intersect_keys = d1_keys.intersection(d2_keys)
    added = d1_keys - d2_keys
    removed = d2_keys - d1_keys
    modified = {o: (d1[o], d2[o]) for o in intersect_keys if d1[o] != d2[o]}
    same = set(o for o in intersect_keys if d1[o] == d2[o])
    return added, removed, modified, same

checkslist = collections.defaultdict(dict)


checkslist['a'][0]="test1"
checkslist['a'][1]="test2"


with open('checklist.json',"w") as outfile:
    json.dump(checkslist,outfile)


with open('checklist.json',"r") as infile:
    data = json.load(infile)

added, removed, modified, same = dict_compare(data, checkslist)
print(added, removed, modified, same)

К сожалению, это не очень хорошо работает. Он обнаруживает его как измененный.

Выход:

(set([]), set([]), {'a': ({u'1': u'test2', u'0': u'test1'}, {0: 'test1', 1: 'test2'})}, set([]))

3-й сет должен быть пустым.

Как правильно сравнить 2 двумерных диктанта?

Спасибо

обновление 1:

checkslistbase = collections.defaultdict(dict)
checkslist = collections.defaultdict(dict)


checkslistbase['a'][0]="test1"
checkslistbase['a'][1]="test2"

checkslist['a'][0]="test1"
checkslist['a'][1]="test3"

Хотите сравнить контрольный список с контрольным списком. В этом случае он должен обнаружить, что контрольный список ['a'] [1] был изменен (изменен). Следует также упомянуть, когда материал был добавлен, удален или что то же самое.

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Третий набор -

{'a': ({u'1': u'test2', u'0': u'test1'}, {0: 'test1', 1: 'test2'})}

Значения для клавиши a:

V1 = {u'1': u'test2', u'0': u'test1'}

V2 = {0: 'test1', 1: 'test2'}

Проблема: V1 отличается от V2, поскольку V1 использует строку в качестве ключей, а V2 использует целое число в качестве ключей.

0 голосов
/ 03 мая 2018

Ваша функция сравнения в порядке.

Проблема в том, что при сериализации словаря целочисленные ключи преобразуются в строки.

checkslist['a'][0]="test1"
checkslist['a'][1]="test2"

когда вы выбрасываете что вы получаете:

{"a": {"0": "test1", "1": "test2"}}

используйте checkslist.copy() для сравнения с data или используйте строковые ключи, и он будет работать с json:

checkslist['a']["0"]="test1"
checkslist['a']["1"]="test2"

(еще одной альтернативой будет сравнение ключей с преобразованием str, но это заставит многое изменить в вашем коде и заставит воссоздать почти каждый ввод)

Если вам нужна альтернативная сериализация только для Python, используйте str(dict(checkslist)), чтобы написать dict (вам нужно преобразовать его в стандартный dict, чтобы иметь возможность проанализировать его обратно) и ast.literal_eval, чтобы проанализировать его обратно, так что различие между целыми числами и строками в словарных ключах сохраняются.

with open('checklist.json',"w") as outfile:
    outfile.write(str(dict(checkslist)))

with open('checklist.json',"r") as infile:
    data = ast.literal_eval(infile.read())

с этими изменениями ваш код печатает (как и ожидалось):

set() set() {} {'a'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...