双向/反向映射

129 投票
15 回答
78924 浏览
提问于 2025-04-15 14:29

我在用Python做一个电话交换机的项目,需要记录谁在和谁说话。比如说,如果爱丽丝(Alice)给鲍勃(Bob)打电话,那就意味着鲍勃也在和爱丽丝通话。

我知道可以用两个哈希表来记录这些信息,但我在想有没有办法只用一个哈希表来实现。

或者有没有其他的数据结构可以推荐。

这里没有多方通话的情况。假设这是一个客服中心,当爱丽丝拨打电话时,她只会和鲍勃说话,而鲍勃的回复也只会给她。

15 个回答

42

我知道这个问题比较老了,但我想提一下另一个很好的解决方案,就是一个叫做 bidict 的Python库。使用起来非常简单:

from bidict import bidict
map = bidict(Bob = "Alice")
print(map["Bob"])
print(map.inv["Alice"])
59

在你的特殊情况下,你可以把两者都放在一个字典里:

relation = {}
relation['Alice'] = 'Bob'
relation['Bob'] = 'Alice'

因为你所描述的是一种对称关系。也就是说,A -> B => B -> A,意思是A和B之间的关系是相互的。

113

你可以通过继承 dict 来创建自己的字典类型,并添加你想要的功能。下面是一个简单的例子:

class TwoWayDict(dict):
    def __setitem__(self, key, value):
        # Remove any previous connections with these values
        if key in self:
            del self[key]
        if value in self:
            del self[value]
        dict.__setitem__(self, key, value)
        dict.__setitem__(self, value, key)

    def __delitem__(self, key):
        dict.__delitem__(self, self[key])
        dict.__delitem__(self, key)

    def __len__(self):
        """Returns the number of connections"""
        return dict.__len__(self) // 2

它的工作方式是这样的:

>>> d = TwoWayDict()
>>> d['foo'] = 'bar'
>>> d['foo']
'bar'
>>> d['bar']
'foo'
>>> len(d)
1
>>> del d['foo']
>>> d['bar']
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
KeyError: 'bar'

我知道我可能没有涵盖所有情况,但这应该能帮助你入门。

撰写回答