Python中用于1:1映射的数据结构?

44 投票
9 回答
18478 浏览
提问于 2025-04-15 11:35

我遇到了一个问题,需要一种可以反向查找的键值对映射。

这意味着有时候我想通过键找到对应的值,而有时候我又想通过值找到对应的键。并且,所有的键和值都是唯一的。

x = D[y]
y == D.inverse[x]

一个明显的解决办法就是每次需要反向查找时,直接把字典反转过来:反转字典其实很简单,这里有个方法,但如果字典很大,速度可能会很慢

另一种选择是创建一个新类,把两个字典结合起来,一个用来查找键,另一个用来查找值。这样做可能会很快,但会消耗两倍的内存。

那么有没有更好的结构可以使用呢?

  • 我的应用需要这个结构非常快,并且尽量少占用内存。
  • 这个结构必须是可变的,并且最好在修改对象时不会变得更慢(比如不需要完全重新索引)。
  • 我们可以保证键或值(或者两者)会是整数。
  • 这个结构可能需要存储成千上万甚至数百万个项目。
  • 键和值都是唯一的,也就是说,len(set(x)) == len(x) 对于 x 在 [D.keys(), D.values()] 中成立。

9 个回答

5

另一种选择是创建一个新的类,把两个字典合在一起,每个字典用来做不同的查找。这种方法可能会用到两倍的内存,因为你有两个字典。

其实并不是这样,因为它们只是指向同一份数据的两个引用。在我看来,这并不是一个坏的解决方案。

你有没有考虑过使用内存数据库来查找?我不太确定它的速度如何,但在关系型数据库中,查找速度可以非常快。

28

另一种选择是创建一个新类,将两个字典结合起来,每种查找用一个字典。这种方法可能会很快,但会消耗两倍于单个字典的内存。

其实并不是这样。你有测量过吗?因为这两个字典会使用相同的对象作为键和值,所以实际上消耗的内存只是字典的结构部分。这远没有两倍那么多,而且无论你的数据大小如何,这个内存消耗都是固定的。

我的意思是,实际的数据不会被复制。所以你只会多花一点点内存。

举个例子:

a = "some really really big text spending a lot of memory"

number_to_text = {1: a}
text_to_number = {a: 1}

只有一份“非常大的”字符串存在,所以你最终只会多花一点内存。这通常是可以接受的。

我无法想象一种解决方案,可以在按值查找时保持键查找的速度,除非你至少花足够的内存来存储一个反向查找的哈希表(这正是你提到的“合并两个dict”解决方案所做的)。

11

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。比如说,当你在写代码时,可能会发现某个功能没有按照预期工作。这时候,很多人会选择去网上寻找答案,像是StackOverflow这样的网站就是一个很好的资源。

在这些网站上,开发者们会分享他们遇到的问题和解决方案。你可以看到很多人提问,然后其他人会给出他们的回答和建议。这种互动不仅能帮助提问者解决问题,也能让其他人学习到新的知识。

总之,遇到问题时,不要害怕去寻求帮助,网络上有很多资源可以利用,尤其是像StackOverflow这样的社区,大家都很乐意分享经验和解决方案。

class TwoWay:
    def __init__(self):
       self.d = {}
    def add(self, k, v):
       self.d[k] = v
       self.d[v] = k
    def remove(self, k):
       self.d.pop(self.d.pop(k))
    def get(self, k):
       return self.d[k]

撰写回答