2016-04-20 2 views
0

Я использую кортежи в качестве ключа для словаря, который я создал. Например:Как игнорировать порядок элементов в кортеже

example_dict = {} 
example_dict[("A", "B")] = "1" 

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

("B", "A") may be the case, instead of ("A", "B") 

Я знаю, что эти кортежи не равны от простого сравнения ==, что я попробовал в оболочке Python.

Что мне интересно, как я могу обойти это? Как я мог сделать не после получения исключения KeyError:

print (example_dict["B", "A"]) 

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

ответ

4

Вы хотите, чтобы ваши словарные ключи были «наборами» (набор - это коллекция, для которой элемент находится либо в или нет в наборе, но не имеет понятия порядка). К счастью, у python есть то, что вам нужно. В частности, потому что вам нужно что-то хешируемое, вы хотите использовать frozenset.

>>> example_dict = {} 
>>> example_dict[frozenset(("A", "B"))] = "1" 
>>> example_dict[frozenset(("B", "A"))] 
'1' 
>>> example_dict[frozenset(("A", "B"))] 
'1' 
+0

Наборы также не имеют понятия множественности элементов. Это не имеет значения, когда ваши кортежи имеют длину 2, но это может быть беспорядочно разбито, когда у вас есть три элемента, и вы не можете отличить '(" A "," A "," B ")' from '(" A " , "B", "B") ', или если ваши кортежи могут иметь разную длину, и вы не можете различать' ("A",) 'from' ("A", "A") '. Он также ломается, если вы попытаетесь сделать что-то вроде 'for a, b в example_dict'. – user2357112

+0

Любые комментарии об эффективности этого? Кажется, что 'frozenset' намного больше, чем 'tuple', с точки зрения объема памяти. – sudo

2

Вместо использования tuple используйте frozenset. A frozenset является константой set, так же как tuple можно назвать константой list.

Вот пример (из Python 3, но он будет работать в Python 2, а):

>>> d = {} 
>>> k1 = frozenset((1, 2)) 
>>> k2 = frozenset((2, 1)) 
>>> k1 
frozenset({1, 2}) 
>>> k2 
frozenset({1, 2}) 
>>> k1 == k2 
True 
>>> d[k1] = 123 
>>> d[k2] 
123 
>>> 
5

обычным способом являются либо отсортировать ключи:

example_dict[tuple(sorted(key_tuple))] = "1" 

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

example_dict[frozenset(key_tuple)] = "1" 

или использовать frozensets из (item, count) кортежи как ключи (если могут быть дублирующие элементы в кортежах):

example_dict[frozenset(Counter(key_tuple).viewitems())] = "1" 

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

Смежные вопросы