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.
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]}
}
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With