如何忽略元组中元素的顺序

时间:2016-04-20 21:40:06

标签: python dictionary tuples

我使用元组作为我创建的字典的键。例如:

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

后来当我想修改字典中条目的值时,我目前无法控制元组的顺序。例如:

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

我知道这些元组与我在python shell中尝试的简单==比较不相等。

我想知道的是我如何解决这个问题?我怎么能使以下不产生KeyError:

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

有没有办法一致地排序元组的元素?有没有办法完全忽略订单?还有其他工作吗?我知道我可以将元组的所有排列都包含在字典中作为键,然后在以后整理不同排列的值。我强烈希望避免这样做,因为这只会增加问题的难度和复杂性。

3 个答案:

答案 0 :(得分:7)

通常的方法是对键进行排序:

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

使用frozensets作为键(如果元组中没有重复的元素):

example_dict[frozenset(key_tuple)] = "1"

或使用(item, count)元组的frozensets作为键(如果元组中可能存在重复元素):

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

无论您选择哪个选项,在查找值时都必须应用相同的转换。

答案 1 :(得分:5)

你希望你的字典键是"设置" (集合是项目在集合中或不在集合中的集合,但没有订单概念)。幸运的是python有你需要的东西。特别是因为你需要一些可以使用的东西,你想使用frozenset

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

答案 2 :(得分:4)

不使用tuple,而是使用frozensetfrozenset只是一个常数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
>>>