Multiples-keys字典,其中键顺序无关紧要

lur*_*gan 10 python dictionary

我正在尝试创建一个包含两个字符串作为键的字典,我希望键可以按任何顺序排列.

myDict[('A', 'B')] = 'something'
myDict[('B', 'A')] = 'something else'
print(myDict[('A', 'B')])
Run Code Online (Sandbox Code Playgroud)

我想要这段代码打印"别的东西".不幸的是,似乎订单与元组有关.什么是最好的数据结构作为关键?

abc*_*ccd 19

用一个 frozenset

而不是tuple有序的,你可以使用a frozenset,这是无序的,而仍然是可变的,因为frozenset不可变的.

myDict = {}
myDict[frozenset(('A', 'B'))] = 'something'
myDict[frozenset(('B', 'A'))] = 'something else'
print(myDict[frozenset(('A', 'B'))])
Run Code Online (Sandbox Code Playgroud)

哪个会打印:

something else
Run Code Online (Sandbox Code Playgroud)

不幸的是,这种简单性带来了缺点,因为frozenset它基本上是一个"冻结"的集合.frozenset例如,在中没有重复的值

frozenset((1, 2)) == frozenset((1,2,2,1,1))
Run Code Online (Sandbox Code Playgroud)

如果减少价值值不打扰你,请随意使用 frozenset

但如果你100%确定你不想要上面提到的内容发生,那么有两个替代方案:


一种方法是使用a 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
Run Code Online (Sandbox Code Playgroud)

第二个方法是使用内置的功能sorted,并使其可哈希通过使一个tuple.这将在用作键之前对值进行排序:( 注意:元组中的所有内容都必须是可排序和可清除的)

myDict = {}
myDict[tuple(sorted(('A', 'B')))] = 'something'
myDict[tuple(sorted(('B', 'A')))] = 'something else'
print(myDict[tuple(sorted(('A', 'B')))])

# something else
Run Code Online (Sandbox Code Playgroud)

但是,如果元组元素既不是可以清洗的,也不是可以排序的,不幸的是,你可能运气不好,需要创建自己的dict结构...... D:

  • 你的`冷冻集(Counter(...))`代码错了:`frozenset(Counter('abc'))`,`frozenset(Counter('abbccc'))`和`frozenset(('a','b' ,'c'))`都是平等的.你想要`frozenset(Counter(xs).iteritems())`(Python 3中的`.items()`). (4认同)