Reputation: 14727
I'm curious if I can transform the following data
old_data = {
"key0": [obj0, obj1],
"key1": [obj2, obj3]
}
to
data = {
"key0": [obj0.id, obj1.id],
"key1": [obj2.id, obj3.id]
}
using dict comprehension.
So basically just replacing those list objects with a single attribute of the object itself. All the objects are from the same type and therefore have the id
attribute for sure.
I came up with the following solution which doesn't work:
data = {
key: [obj.id]
for key, obj_list in old_data.items()
for obj in obj_list
}
The resulting dictionary just contains lists with exactly one value (the last value which was iterated) because of this line:
key: [obj.id]
creates every time just a new list with one value.
So I instead of creating a new list, I wanted to append
new obj_id
s to an existing list, but I don't know how.
I think it must look somehow like this:
key: data[key].append(obj.id)
But obviously this also can't work because data
isn't assigned yet and even if it would be: the first obj.id
couldn't be appended because the list was never initialized.
(I'm using Python 3.7)
Upvotes: 0
Views: 465
Reputation: 26281
Here's a not so very pythonic, but still interesting way of doing it:
from functools import partial
from operator import attrgetter
old_data = {
"key0": [obj0, obj1],
"key1": [obj2, obj3]
}
data = dict(zip(old_data, map(list, map(partial(map, attrgetter('id')), old_data.values()))))
Upvotes: 1
Reputation: 14727
So I found a solution using list comprehension:
data = {
key: [obj.id for obj in obj_list]
for key, obj_list in old_data.items()
}
Just had to move the loop (for obj in obj_list
) inside the list comprehension.
This also solves the problem that for the first obj
no list exists and further that no other obj
s need the append
method or something like this.
Upvotes: 0