Oedipus
Oedipus

Reputation: 143

How to add multiple values to a key in a Python dictionary

I am trying to create a dictionary from the values in the name_num dictionary where the length of the list is the new key and the name_num dictionary key and value are the value. So:

name_num = {"Bill": [1,2,3,4], "Bob":[3,4,2], "Mary": [5, 1], "Jim":[6,17,4], "Kim": [21,54,35]}

I want to create the following dictionary:

new_dict = {4:{"Bill": [1,2,3,4]}, 3:{"Bob":[3,4,2], "Jim":[6,17,4], "Kim": [21,54,35]}, 2:{"Mary": [5, 1]}}

I've tried many variations, but this code gets me the closest:

for mykey in name_num:
    new_dict[len(name_num[mykey])] = {mykey: name_num[mykey]}

Output:

new_dict = {4:{"Bill": [1,2,3,4]}, 3:{"Jim":[6,17,4]}, 2:{"Mary": [5, 1]}}

I know I need to loop through the code somehow so I can add the other values to key 3.

Upvotes: 7

Views: 13768

Answers (3)

Ozgur Vatansever
Ozgur Vatansever

Reputation: 52093

Just an alternative to others; you can sort by length and use itertools.groupby:

>>> result = {}
>>> f = lambda t: len(t[1])
>>> for length, groups in itertools.groupby(sorted(name_num.items(), key=f), key=f):
...     result[length] = dict((k, v) for k, v in groups)
>>> print result
{
    2: {'Mary': [5, 1]},
    3: {'Bob': [3, 4, 2], 'Jim': [6, 17, 4], 'Kim': [21, 54, 35]},
    4: {'Bill': [1, 2, 3, 4]}
}

In a worst case scenario where each inner list has a different length, this performs O(n^2) which is fairly inefficient compared to other solutions posted above.

Upvotes: 4

Jezor
Jezor

Reputation: 3426

Dictionary, associative array or map (many names, basically the same functionality) property is that keys are unique.

The keys you wish to have, which are integers, are not unique if lengths are the same, that's why your code doesn't work. Putting a new value for existing key means replacing the old value.

You have to add key-value pairs to the existing value dictionaries.

for mykey in name_num:
    length = len(name_num[mykey])
    if length in new_dict: # key already present in new dictionary
        new_dict[length][mykey] = name_num[mykey]
    else:
        new_dict[length] = {mykey: name_num[mykey]}

should do the trick

Upvotes: 5

Karin
Karin

Reputation: 8600

This is a good use case for defaultdict:

from collections import defaultdict
name_num = {
    'Bill': [1, 2, 3, 4],
    'Bob': [3, 4, 2],
    'Mary': [5, 1],
    'Jim': [6, 17, 4],
    'Kim': [21, 54, 35],
}

new_dict = defaultdict(dict)
for name, nums in name_num.items():
    new_dict[len(nums)][name] = nums

print(dict(new_dict))

Output:

{
    2: {'Mary': [5, 1]},
    3: {'Bob': [3, 4, 2], 'Jim': [6, 17, 4], 'Kim': [21, 54, 35]},
    4: {'Bill': [1, 2, 3, 4]}
}

Upvotes: 21

Related Questions