Ответ 1
Используйте frozenset
Вместо tuple
, который упорядочен, вы можете использовать frozenset
, который является неупорядоченным, но все еще хешируется, поскольку frozenset
является неизменным.
myDict = {}
myDict[frozenset(('A', 'B'))] = 'something'
myDict[frozenset(('B', 'A'))] = 'something else'
print(myDict[frozenset(('A', 'B'))])
Что будет печатать:
something else
К сожалению, эта простота имеет недостаток, поскольку frozenset
- это в основном "замороженный" набор. Не будет повторяющихся значений в frozenset
, например,
frozenset((1, 2)) == frozenset((1,2,2,1,1))
Если обрезка значений не беспокоит вас, не стесняйтесь использовать frozenset
Но если вы на 100% уверены, что не хотите того, что было упомянуто выше, есть, однако, две альтернативы:
Первый способ - использовать Counter
и сделать его hashable
с помощью frozenset
снова: (Примечание: все в кортеже должно быть хешируемым)
from collections import Counter
myDict = {}
myDict[frozenset(Counter(('A', 'B')).items())] = 'something'
myDict[frozenset(Counter(('B', 'A')).items())] = 'something else'
print(myDict[frozenset(Counter(('A', 'B')).items())])
# something else
Второй способ - использовать встроенную функцию sorted
и сделать ее хешируемой, сделав ее tuple
. Это будет сортировать значения перед использованием в качестве ключа: (Примечание: все в кортеже должно быть сортируемым и хешируемым)
myDict = {}
myDict[tuple(sorted(('A', 'B')))] = 'something'
myDict[tuple(sorted(('B', 'A')))] = 'something else'
print(myDict[tuple(sorted(('A', 'B')))])
# something else
Но если элементы кортежа не являются ни хэшируемыми, ни все они не сортируемы, к сожалению, вам может быть не повезло и вам нужно создать свою собственную структуру dict... D: