Как проверить, являются ли два списка словарей (где элемент dict содержит список) одинаковыми - PullRequest
3 голосов
/ 13 марта 2020

Я создаю свой первый тестовый скрипт (ууу!) У меня есть список словарей, где один из ключей - это список. Я бы хотел, чтобы тест прошел, если список (в словаре) находится в любом порядке. Я знаю, что вы можете использовать assertCountEqual для проверки равенства списков независимо от порядка, но можете ли вы сделать это для списка, который содержит список списков? См. Ниже, например,

Удастся

def test(self):
    output = [2,1]
    desired_output = [1,2]
    self.assertCountEqual(output, desired_output)

Сбой

def test(self):
    desired_output = [{'count': 2, 'columns': ['col2', 'col5']}]
    output = [{'count': 2, 'columns': ['col5', 'col2']}]
    self.assertCountEqual(output, desired_output)

Спасибо

1 Ответ

3 голосов
/ 13 марта 2020

assertCountEqual(first, second, msg=None):

Проверка, что последовательность сначала содержит те же элементы, что и вторая, независимо от их порядка. В противном случае будет сгенерировано сообщение об ошибке с указанием различий между последовательностями.

Важно:

Вызов assertCountEqual(first, second, msg=None) эквивалентен вызову assertEqual(Counter(list(first)), Counter(list(second))).

Примечание:

Счетчик - это подкласс dict для подсчета хеш-объектов. Это коллекция, в которой элементы хранятся в виде словарных ключей, а их значения хранятся в виде значений словаря Чтобы это работало, ключи должны быть hashable, но, к сожалению, dict - это unhashable, потому что он изменчив.


Чтобы выполнить желаемое задание, вы можете использовать frozenset. frozenset создает неизменяемый неупорядоченный набор уникальных элементов. Чтобы тест прошел успешно, вам нужно будет создать dict, значения которого, соответствующие его ключам, являются неизменяемыми. Мы можем использовать рекурсивный подход для создания словаря, который содержит неизменяемые значения.

Попробуйте это (ОБНОВЛЕНИЕ):

def getHashableDict(dictionary):
    hashable_dict = {}
    for key, value in dictionary.items():
        if isinstance(value, list):
            hashable_dict[key] = frozenset(value)
        elif isinstance(value, dict):
            hashable_dict[key] = getHashableDict(value)
        else:
            hashable_dict[key] = value

    return frozenset(hashable_dict.items())

def test(self):
    desired_output = [{'count': 2, 'columns': ['col2', 'col5']}]
    output = [{'count': 2, 'columns': ['col5', 'col2']}]

    output = [getHashableDict(item) for item in output] #--> create list of hashable types
    desired_output = [getHashableDict(item) for item in desired_output]

    self.assertCountEqual(output, desired_output)

Тест теперь будет успешным .

...