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

Я смотрел на это Разницу между кортежами и замороженными наборами в Python и привел меня на этот вопрос для моей проблемы

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

Я пытаюсь создать набор данных этого типа для проверки различных значений, таких как (1,2,3), следует рассматривать так же, как (1,3,2). Я знаю, что одним из решений было бы использовать список, упорядочить его, а затем сделать его кортежем, но мне приходится делать это много раз, и длина кортежа может быть большой, поэтому я бы предпочел не сортировать каждый раз, если это возможно.

РЕДАКТИРОВАТЬ:

проблема немного изменилась. теперь у меня есть список кортежей, например: list_tuple = [(2, 2, 2), (2, 2, 2), (2, 1, 1)]

проблема не сильно изменилась, у кортежей есть порядок, который имеет значение, но порядок кортежей не имеет значения. так, например, это идентично предыдущему: [(2, 2, 2), (2, 1, 1), (2, 2, 2)] я получу много из них, которые я хочу добавить к набор, чтобы я мог подсчитать количество различных списков кортежей. так что на самом деле у меня та же проблема с порядком, не имеющим значения, и разрешенными дубликатами, за исключением того, что вместо целых чисел мы имеем дело с кортежами.

Я предположил, что должен просто отсортировать список кортежей, затем сделать список кортежем, и он может войти в набор и работать правильно. Я знаю, что сказал, что не хочу сортировать, но я не вижу другого пути.

Спасибо


person bupp    schedule 25.10.2019    source источник
comment
Вы можете проверить ответы здесь: stackoverflow.com/questions/55267781/   -  person Ryan    schedule 25.10.2019
comment
Итак, вам нужен неизменяемый collections.Counter?   -  person Aran-Fey    schedule 25.10.2019
comment
@Aran-Fey: мне кажется, это больше похоже на мультисет, которого, насколько мне известно, нет ни в одном из стандартные модули (или встроенные).   -  person martineau    schedule 25.10.2019
comment
Счетчик в основном представляет собой мультимножество; он просто не хранит каждый объект явно, а скорее подсчет, который указывает, сколько раз вам нужно будет включить объект в итерацию по элементам. Между {{'a', 'a', 'b'}} (чтобы создать синтаксис для многошаговой обработки) и Counter({'a': 2, 'b': 1}) мало значимой разницы.   -  person chepner    schedule 26.10.2019
comment
@chepner: Я полагаю, это правда. Между прочим, на pypi есть модуль multiset.   -  person martineau    schedule 26.10.2019


Ответы (1)


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

>>> from collections import Counter
>>> from types import MappingProxyType
>>> d1 = MappingProxyType(Counter("aab"))
>>> d2 = MappingProxyType(Counter("aba"))
>>> d1 == d2
True

Насколько мне известно, нет способа получить ссылку на базовые объекты Counter, чтобы вы могли их модифицировать.

Вам просто нужно немного поработать, чтобы перебрать дубликаты; к счастью, модуль itertools выполняет большую часть тяжелой работы.

>>> from itertools import chain, startup, repeat
>>> list(chain.from_iterable(starmap(repeat, d1.items())))
['a', 'a', 'b']
>>> list(chain.from_iterable(starmap(repeat, d2.items())))
['a', 'a', 'b']
person chepner    schedule 25.10.2019
comment
спасибо за комментарий, проверьте мое редактирование. Счетчик будет работать для представления моих данных, но затем мне нужно добавить его в набор, потому что я хочу подсчитать количество отдельных списков кортежей. но Counter не является хешируемым и, насколько я могу судить, является MappingProxyType. Сначала я сказал, что не хочу сортировать, но, возможно, это единственный вариант, отсортировать список кортежей, сделать список кортежей кортежем кортежей, а затем добавить его в набор. Это покроет мой случай, но дайте мне знать, если вы думаете, что есть лучший способ сделать это. - person bupp; 26.10.2019
comment
Я не понимаю, зачем вам нужно Counter или MappingProxyType для хеширования. MappingProxyType(Counter([(2,2,2), (2,2,1), (2,2,2)])). - person chepner; 26.10.2019
comment
Я могу упустить то, что делает для меня MappingProxyType, но Counter([(2,2,2), (2,2,1), (2,2,2)]) — это всего лишь один экземпляр, который у меня будет, скажем, куча из них, и мне нужно считать отдельные. Добавление их в набор кажется наиболее эффективным способом сделать это, в отличие от списка, в котором я должен проверить, есть ли он там. так как iirc похож на O (n) для списка, но O (1) для наборов, поэтому я хочу, чтобы он был хешируемым. извините, если я просто не понимаю - person bupp; 26.10.2019
comment
Хорошо, я вижу, ваша изменившаяся проблема теперь совсем другая. Я думал, что вы переходите от мультимножеств (скажем) int к мультимножествам кортежей, но вы переходите от мультимножеств кортежей к мультимножествам мультимножеств кортежей. - person chepner; 26.10.2019
comment
Да, точно. я мог бы просто отсортировать отдельные группы кортежей в списке, а затем сделать это кортежем, тогда я могу просто использовать set () ... возможно, в любом случае это слишком сложно. не хотел перечислять проблему, которую я решаю, потому что я хотел попытаться понять это самостоятельно, но в основном пытался найти уникальные поддеревья с точки зрения их формы. поэтому я пытаюсь каким-то образом превратить форму дерева в самое простое представление, с которым у меня были проблемы. (2,2,2), (2,2,1), (2,2,2) означает, что корень имеет 2 дочерних элемента, и каждый кортеж представляет собой путь от маршрута, представляемого им # дочерних элементов - person bupp; 26.10.2019