asfeynman asfeynman - 1 year ago 73
Python Question

I need a way to map multiple keys to the same value in a dictionary

Admittedly, this question seems like it might be a popular one, but I couldn't really find it (perhaps I wasn't using the right search terms). Anyway, I need something of this sort:

tel = {}
tel['1 12'] = 1729
tel['9 10'] = 1729
tel['1 2'] = 9
tel['2 1'] = 9
tel['1 1'] = 2

{['1 1'] : 2, ['1 2', '2 1'] : 9, ['1 12', '9 10'] : 1729}

So whenever a key's value is already in the dict, append the key to the list of keys mapping to that value; else, add the key value pair to the dict.

I'm sorry if I confused the lot of you, and I'm REALLY sorry if the following confuses you even more :)

This is the original problem I wanted to solve: Given the equation a^3 + b^3, produce a dictionary mapping all positive integer pair values for a, b less than 1000 to the value of the equation when evaluated. When two pairs evaluate to the same value, I want the two pairs to share the same value in the dictionary and be grouped together somehow. (I'm already aware that I can map different keys to the same value in a dict, but I need this grouping).

So a sample of my pseudocode would be given by:

for a in range(1, 1000):
for b in range(1, 1000):
map pair (a, b) to a^3 + b^3

For some integer pairs (a, b) and (p, q) where a != p, and b != q, a^3 + b^3 == p^3 + q^3. I want these pairs to be grouped together in some way. So for example, [(1, 12), (9, 10)] maps to 1729. I hope this makes it more clear what I want.

As many of you have pointed out, I shall switch the key value pairs if it means a faster lookup time. That would mean though that the values in the key:value pair need to be tuples.

Answer Source

As many of the comments have already pointed out, you seem to have your key/value structure inverted. I would recommend factoring out your int values as keys instead. This way you achieve efficient dictionary look ups using the int value as a key, and implement more elegant simple design in your data - using a dictionary as intended.

Ex: {9: ('1 2', '2 1'), 2: ('1 1',), 1729: ('9 10', '1 12')}

That being said the snippet below will do what you require. It first maps the data as shown above, then inverts the key/values essentially.

tel = {}
tel['1 12'] = 1729
tel['9 10'] = 1729
tel['1 2'] = 9
tel['2 1'] = 9
tel['1 1'] = 2
from collections import defaultdict

new_tel = defaultdict(tuple)
for key, value in tel.items():
    new_tel[value] += (key,)

print {key:value for value, key in new_tel.items()}
>>> {('1 2', '2 1'): 9, ('1 1',): 2, ('9 10', '1 12'): 1729}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download