Python3 сортирует списки вложенных диктов с помощью лямбды - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть глубоко вложенный объект различных списков и диктов, который я извлекаю как json, который мне нужно сравнить с другой версией самого себя. Проблема в том, что все списки в основном не отсортированы, поэтому мне нужно отсортировать их перед сравнением. Любая библиотека глубоких разногласий, которую я пробовал, не выполнялась без надлежащей сортировки позиции в списках, поэтому мы приступаем.

Пример объекта, который требует сортировки:

{
    "main":{
        "key1":"value1",
        "key2":"value2",
        "key3":[{
            "sub1":"value2",
            "sub2":{
                "subsub":[{
                    "subsubsub1":10,
                    "subsubsub2":11,
                    "subsubsub3":[10,11,12]
                },{
                    "subsubsub1":7,
                    "subsubsub2":8,
                    "subsubsub3":[9,7,8]
                }]
            }
        },{
            "sub1":"value1",
            "sub2":{
                "subsub":[{
                    "subsubsub1":1,
                    "subsubsub2":2,
                    "subsubsub3":[1,2,3]
                },
                {
                    "subsubsub1":4,
                    "subsubsub2":5,
                    "subsubsub3":[5,6,4]
                }]
            }
        }]
    }
}

Помимо нескольких рекурсивных циклов, я пытаюсь отсортировать сообщения, переводя их с отсортированными списками в отсортированные кортежи и хешируя их.

Edit: Объект передан в unnest ()

    def unnest(d):
    for k, v in d.items():
        if isinstance(v, dict):
            d.update({k: unnest(v)})
        elif isinstance(v, list):
            d.update({k: unsort(v)})
    return d


def unsort(l):
    for i, e in enumerate(l):
        if isinstance(e, dict):
            l[i] = unnest(e)
        elif isinstance(e, list):
            l[i] = unsort(e)
    return sorted(l, key=lambda i: sort_hash(i))


def unnest_hash(d):
    for k, v in d.items():
        if isinstance(v, dict):
            d.update({k: unnest_hash(v)})
        elif isinstance(v, list):
            d.update({k: sort_hash(v)})
    return hash(tuple(sorted(d.items())))


def sort_hash(l):
    if isinstance(l, list):
        for i, e in enumerate(l):
            if isinstance(e, dict):
                l[i] = unnest_hash(e)
            elif isinstance(e, list):
                l[i] = sort_hash(e)
        return hash(tuple(sorted(l)))
    elif isinstance(l, dict):
        return unnest_hash(l)
    else:
        return hash(l)

Однако по какой-то причине значение хеша записывается в «отсортированный» список:

{'main': {'key1': 'value1', 'key2': 'value2', 'key3': [{'sub1': 'value2', 'sub2': -4046234112924644199}, {'sub1': 'value1', 'sub2': 4015568797712784641}]}}

Как я могу предотвратить запись значения сортировки в лямбда-функции в возвращенный отсортированный список? Спасибо!

1 Ответ

0 голосов
/ 11 сентября 2018

Ваша sort_hash функция изменяет переданное ей значение.Вот почему вы видите, что в исходных значениях есть сортировка:

l[i] = unnest_hash(e)

и

 l[i] = sort_hash(e)

, оба изменяют значение, которое вы пытаетесь хэшировать.unnest_hash также изменяет исходные значения:

d.update({k: unnest_hash(v)})

Расчет хеша для сортировки никогда не должен изменять значение, которое он хэширует.

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