我正试图创建一个以两个字符串作为键的字典,并且我希望这些键按任何顺序排列。
myDict[('A', 'B')] = 'something'
myDict[('B', 'A')] = 'something else'
print(myDict[('A', 'B')])我要这段代码打印“其他东西”。不幸的是,排序似乎与元组有关。什么才是最好的数据结构作为关键?
发布于 2017-10-08 15:59:42
与排序的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,并通过再次使用frozenset使其成为hashable:(注释:元组中的所有内容都必须是 hashable)
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。这将在用作键之前对值进行排序:(注释:元组中的所有内容都必须是、可排序的和 hashable)。
myDict = {}
myDict[tuple(sorted(('A', 'B')))] = 'something'
myDict[tuple(sorted(('B', 'A')))] = 'something else'
print(myDict[tuple(sorted(('A', 'B')))])
# something else但是如果元组元素既不都是可选的,也不都是可排序的,那么不幸的是,您可能运气不好,需要创建自己的断块结构……D:
发布于 2017-10-08 16:02:59
你可以建立你自己的结构:
class ReverseDict:
def __init__(self):
self.d = {}
def __setitem__(self, k, v):
self.d[k] = v
def __getitem__(self, tup):
return self.d[tup[::-1]]
myDict = ReverseDict()
myDict[('A', 'B')] = 'something'
myDict[('B', 'A')] = 'something else'
print(myDict[('A', 'B')])输出:
something else发布于 2019-05-15 03:12:29
我认为这里的要点是,元组的元素指向同一个字典元素,而不管它们的顺序如何。这可以通过使散列函数对元组关键元素进行交换来实现:
class UnorderedKeyDict(dict):
def __init__(self, *arg):
if arg:
for k,v in arg[0].items():
self[k] = v
def _hash(self, tup):
return sum([hash(ti) for ti in tup])
def __setitem__(self, tup, value):
super().__setitem__(self._hash(tup), value)
def __getitem__(self, tup):
return super().__getitem__(self._hash(tup))
mydict = UnorderedKeyDict({('a','b'):12,('b','c'):13})
mydict[('b','a')]
>> 12https://stackoverflow.com/questions/46633065
复制相似问题