[python] 양방향 / 역지도 [중복]

저는 파이썬에서이 스위치 보드 작업을하고 있습니다. 여기서 누가 누구와 이야기하고 있는지 추적해야합니다. 따라서 Alice-> Bob이라면 이는 Bob-> Alice를 의미합니다.

예, 두 개의 해시 맵을 채울 수 있지만 누군가 하나로 할 아이디어가 있는지 궁금합니다.

또는 다른 데이터 구조를 제안하십시오.

여러 대화가 없습니다. 이것이 고객 서비스 콜 센터 용이라고 가정 해 보겠습니다. Alice가 스위치 보드에 전화를 걸면 그녀는 Bob 과만 대화 할 것입니다. 그의 대답은 그녀에게만 전달됩니다.



답변

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'

모든 사례를 다루지는 않았지만 시작해야합니다.


답변

특별한 경우에는 둘 다 하나의 사전에 저장할 수 있습니다.

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

당신이 설명하는 것은 대칭 관계이기 때문입니다. A -> B => B -> A


답변

나는 그것이 오래된 질문이라는 것을 알고 있지만이 문제에 대한 또 다른 훌륭한 해결책, 즉 python package bidict 를 언급하고 싶었 습니다 . 사용하는 것은 매우 간단합니다.

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


답변

두 번째 해시를 채울 것입니다.

reverse_map = dict((reversed(item) for item in forward_map.items()))


답변

메모리를 절약 할 수 있다고 가정하면 두 개의 해시 맵이 실제로 가장 빠른 성능의 솔루션 일 것입니다. 나는 그것들을 단일 클래스로 래핑 할 것입니다. 프로그래머의 부담은 두 개의 해시 맵이 올바르게 동기화되도록하는 것입니다.


답변

두 가지 문제가 있습니다.

  1. “대화”개체가 있습니다. 두 사람을 의미합니다. 한 사람이 여러 대화를 할 수 있기 때문에 다 대다 관계가 있습니다.

  2. 사람에서 대화 목록으로의지도가 있습니다. 전환에는 한 쌍의 사람이 있습니다.

이렇게하세요

from collections import defaultdict
switchboard= defaultdict( list )

x = Conversation( "Alice", "Bob" )
y = Conversation( "Alice", "Charlie" )

for c in ( x, y ):
    switchboard[c.p1].append( c )
    switchboard[c.p2].append( c )


답변

아니요, 두 개의 사전을 만들지 않고는이를 수행 할 수있는 방법이 없습니다. 비슷한 성능을 계속 제공하면서 단 하나의 사전으로 이것을 구현하는 것이 어떻게 가능할까요?

두 개의 사전을 캡슐화하고 원하는 기능을 노출하는 사용자 지정 형식을 만드는 것이 좋습니다.