首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >多键字典中的键顺序不重要

多键字典中的键顺序不重要
EN

Stack Overflow用户
提问于 2017-10-08 15:54:10
回答 3查看 1.6K关注 0票数 11

我正试图创建一个以两个字符串作为键的字典,并且我希望这些键按任何顺序排列。

代码语言:javascript
运行
复制
myDict[('A', 'B')] = 'something'
myDict[('B', 'A')] = 'something else'
print(myDict[('A', 'B')])

我要这段代码打印“其他东西”。不幸的是,排序似乎与元组有关。什么才是最好的数据结构作为关键?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-10-08 15:59:42

使用frozenset

与排序的tuple不同,您可以使用无序的frozenset,而frozenset仍然是不可变的。

代码语言:javascript
运行
复制
myDict = {}
myDict[frozenset(('A', 'B'))] = 'something'
myDict[frozenset(('B', 'A'))] = 'something else'
print(myDict[frozenset(('A', 'B'))])

它将打印:

代码语言:javascript
运行
复制
something else

不幸的是,这种简单性有一个缺点,因为frozenset基本上是一个“冻结”集。例如,在frozenset中不会有重复的值,

代码语言:javascript
运行
复制
frozenset((1, 2)) == frozenset((1,2,2,1,1))

如果对值的削减没有困扰您,可以随意使用frozenset

但是,如果您100%肯定不希望发生上述情况,那么有两个备选方案:

第一种方法是使用Counter,并通过再次使用frozenset使其成为hashable:(注释:元组中的所有内容都必须是 hashable)

代码语言:javascript
运行
复制
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)。

代码语言:javascript
运行
复制
myDict = {}
myDict[tuple(sorted(('A', 'B')))] = 'something'
myDict[tuple(sorted(('B', 'A')))] = 'something else'
print(myDict[tuple(sorted(('A', 'B')))])

# something else

但是如果元组元素既不都是可选的,也不都是可排序的,那么不幸的是,您可能运气不好,需要创建自己的断块结构……D:

票数 24
EN

Stack Overflow用户

发布于 2017-10-08 16:02:59

你可以建立你自己的结构:

代码语言:javascript
运行
复制
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')])

输出:

代码语言:javascript
运行
复制
something else
票数 1
EN

Stack Overflow用户

发布于 2019-05-15 03:12:29

我认为这里的要点是,元组的元素指向同一个字典元素,而不管它们的顺序如何。这可以通过使散列函数对元组关键元素进行交换来实现:

代码语言:javascript
运行
复制
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')]
    >> 12
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46633065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档