I'm iterating over a list of objects that have three int attributes: start
, end
, data
. And I'm trying to add all numbers from start
up until end
as keys to a dictionary, with the value being a set containing data
. So, for example, if objects are:
import types
objects_list = [types.SimpleNamespace( start=5, end=8, data=2 ),
types.SimpleNamespace( start=6, end=12, data=6 ),
types.SimpleNamespace( start=10, end=11, data=5 ),
types.SimpleNamespace( start=20, end=22, data=4 )]
for each object I want to add all numbers in range(start, end 1) as dictionary keys, which in case of the first object would be numbers from 5 to 8, each one with a set containing number 2. For the second object I'll add keys 9 to 12 with a set containing number 6, however I'll need to update keys 6, 7 and 8 to add number 6 to the set (which already contained 2). For the third object I'll need to update keys 10 and 11 to add element 5. And for the last object I'll just add keys 20 to 22 with a set containing number 4.
So the dictionary I want to get would have int:set pairs as follows:
5: {2}
6: {2,6}
7: {2,6}
8: {2,6}
9: {6}
10: {6,5}
11: {6,5}
12: {6}
20: {4}
21: {4}
22: {4}
I've been trying to avoid a nested loop by iterating over the list of objects and updating the dict, like this:
my_dict={}
for o in objects_list:
my_dict.update(
dict.fromkeys(range(o.start, o.end 1), set([o.data]))
)
but of course this creates a new set every time set() is called, overwriting old values.
So I'm not sure if there's a way to create the set in case it doesn't exist, or else add the element to it. Because what I'm getting right now is the following dictionary:
{5: {2}, 6: {6}, 7: {6}, 8: {6}, 9: {6}, 10: {5}, 11: {5}, 12: {6}, 20: {4}, 21: {4}, 22: {4}}
Or maybe I'm just missing the whole point and should be doing this in a different way?
CodePudding user response:
It should be like this:
my_dict={}
for o in objects_list:
for i in range(o.start, o.end 1):
if i in my_dict:
my_dict[i].add(o.data)
else:
my_dict[i] = set([o.data])
There is no way to avoid the use of nested loops in your case because you need to add data to the value of the key if it exists and if not you need to create it first.
CodePudding user response:
You can use defaultdict and dict update function
from collections import defaultdict
my_dict = defaultdict(set)
my_dict.update({i: {o.data} for o in objects_list for i in range(o.start, o.end 1)})