Неупорядоченная коллекция для непригодных предметов? - PullRequest
6 голосов
/ 01 декабря 2011

У меня есть диктат, в котором некоторые значения не могут быть хэшируемыми.Мне нужен какой-то способ сравнить две неупорядоченные группы из них, чтобы убедиться, что они содержат одинаковые элементы.Я не могу использовать списки, потому что равенство списков учитывает порядок, но наборы не будут работать, потому что dicts не являются хэшируемыми.Я просмотрел документы по Python, и единственное, что выглядит полезным, это представление dict, которое может быть исправлено при некоторых обстоятельствах, но в этом случае это не помогает, так как одно из значений - это объект, который содержит сами спискиЭто означает, что представление dict также не может быть хэшдругой список?

Ответы [ 2 ]

11 голосов
/ 01 декабря 2011

Когда повторяющихся записей не существует, обычные варианты:

  1. Если элементы являются хэшируемыми: set(a) == set(b)

  2. Если элементы можно заказать: sorted(a) == sorted(b)

  3. Если все, что у вас есть, это равенство: len(a) == len(b) and all(x in b for x in a)

Если у вас есть дубликаты и их кратность имеет значение, варианты:

  1. Если элементы являются хэшируемыми: Counter(a) == Counter(b)

  2. Если элементы можно заказать: sorted(a) == sorted(b)

  3. Если все, что у вас есть, это равенство: len(a) == len(b) and all(a.count(x) == b.count(x) for x in a)

2 голосов
/ 01 декабря 2011

Я думаю, что самый простой способ - это использовать списки.

group_1 = my_dict_1.values()
group_2 = my_dict_2.values()

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

def contain_the_same(group_1, group_2):
    for item in group_1:
        if item not in group_2:
            return False
        else:
            group_2.pop(group_2.index(item))
    if len(group_2) != 0:
        return False
    return True

Это должно быть в состоянии обработатьНежелательные объекты просто отлично:

>>> contain_the_same([1,2,3], [1,2,3])
True
>>> contain_the_same([1,2,3], [1,2,3,4])
False
>>> contain_the_same([1,2,[3,2,1]], [1,2,[3,2,1]])
True
>>> contain_the_same([5,1,2,[3,2,1,[1]]], [1,[3,2,1,[1]],2,5])
True

Предупреждение: Это вернет false, если в одном списке есть дубликаты, а в другом нет.Это потребует некоторой модификации, если вы захотите сделать это допустимым случаем.

Редактировать: Еще проще:

sorted(my_dict_1.values()) == sorted(my_dict_1.values())

Даже выглядит так, что это в два раза быстреекак моя contain_the_same функция:

>>> timeit("contain_the_same([5,1,2,[3,2,1,[1]]], [1,[3,2,1,[1]],2,5])", 
           "from __main__ import contain_the_same", number=10000)/10000
8.868489032757054e-06
>>>timeit("sorted([5,1,2,[3,2,1,[1]]]) == sorted([1,[3,2,1,[1]],2,5])",
           number=10000)/10000
4.928951884845034e-06

Хотя это было бы не так легко распространить на случай, когда допускаются дубликаты.

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