tags:

views:

488

answers:

7

I'm doing this switchboard thing in python where I need to keep track of who's talking to whom, so if Alice --> Bob, then that implies that Bob --> Alice.

Yes, I could populate two hash maps, but I'm wondering if anyone has an idea to do it with one.

Or suggest another data structure.

EDIT: There are no multiple conversations. Lets say this is for a customer service call center, so when Alice dials into the switchboard, she's only going to talk to Bob. His replies also go only to her.

+2  A: 

No, there is really no way to do this without creating two dictionaries. How would it be possible to implement this with just one dictionary while continuing to offer comparable performance?

You are better off creating a custom type that encapsulates two dictionaries and exposes the functionality you want.

Andrew Hare
+3  A: 

Two hash maps is actually probably the fastest-performing solution assuming you can spare the memory. I would wrap those in a single class - the burden on the programmer is in ensuring that two the hash maps sync up correctly.

Triptych
+1  A: 

I would just populate a second hash, with

reverse_map = dict((reversed(item) for item in forward_map.items()))
Ian Clelland
+9  A: 

In your special case you can store both in one dictionary:

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

Since what you are describing is a symmetric relationship. A -> B => B -> A

Nadia Alramli
Hmm... yeah, I like this one the best. Was trying to avoid making two entries, but this is the best idea so far.
Sudhir Jonathan
Still think a two way map ought to be possible :-/
Sudhir Jonathan
If it has to be efficient, then under the covers you need both keys to be indexed in some index data structure — whether that's a hash, a sorted list, a binary tree, a trie, a suffix array full of sistrings, or something even more exotic. The simple way to do that in Python is to use a hash.
Kragen Javier Sitaker
+4  A: 

You have two separate issues.

  1. You have a "Conversation" object. It refers to two Persons. Since a Person can have multiple conversations, you have a many-to-many relationship.

  2. You have a Map from Person to a list of Conversations. A Conversion will have a pair of Persons.

Do something like this

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 )
S.Lott
A: 

Here is a simple bijective Dictionary implementation, although I don't know if it will meet your performance requirements.

(Link from this blog article on boost Bimap for Python, which has some nice discussion of the topic.)

system PAUSE
A: 

The kjbuckets C extension module provides a "graph" data structure which I believe gives you what you want.

Kragen Javier Sitaker
Sorry I didn't mention it, but its on app engine... so no C extensions.
Sudhir Jonathan