Reputation: 1255
I am newbie in Python. I have a list of dictionary which look like as below
[
{
'key1': 'value1',
'key2': [
{
'id': 1,
'name': 'name1'
},
{
'id': 2,
'name': 'name2'
},
{
'id': 3,
'name': 'name3'
}
]
},
{
'key1': 'value1',
'key2': [
{
'id': 1,
'name': 'name1'
},
]
},
{
'key1': 'value1',
'key2': [
{
'id': 1,
'name': 'name1'
},
]
}
]
I want to convert this list into lists of list on the basic of common key2-id, The resultant list will look like
[
[
{
'key1': 'value1',
'key2': [
{'id': 2, 'name': 'name2'},
{'id': 3, 'name': 'name3'}]}
],
[
{
'key1': 'value1',
'key2': [{'id': 1, 'name': 'name1'}]
},
{
'key1': 'value1',
'key2': [{'id': 1, 'name': 'name1'}]
},
{
'key1': 'value1',
'key2': [{'id': 1, 'name': 'name1'}]}
]
]
I have tried to accomplish this using gropby
from itertool as below:
from itertools import groupby
def _group_by_key2_ids(results):
groupby_iterator = groupby(
results,
lambda x: [item.get('id') for item in x.get('key2')]
)
return [list(x) for _, x in groupby_iterator]
It doesn't give the result that I want. Its output look like
[
[
{
'key1': 'value1',
'key2': [
{'id': 1, 'name': 'name1'},
{'id': 2, 'name': 'name2'},
{'id': 3, 'name': 'name3'}]}
],
[
{
'key1': 'value1',
'key2': [{'id': 1, 'name': 'name1'}]
},
{
'key1': 'value1',
'key2': [{'id': 1, 'name': 'name1'}]}]
]
Please let me know, how we can do this. Any help would be appreciated. Thanks.
Upvotes: 5
Views: 98
Reputation: 71471
You can flatten the data and apply itertools.groupby
:
import itertools
data = [{'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}, {'id': 2, 'name': 'name2'}, {'id': 3, 'name': 'name3'}]}, {'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}]}, {'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}]}]
new_d = sorted([(i, a['key1']) for a in data for i in a['key2']], key=lambda x:x[0]['id'])
result = [[{'key1':d, 'key2':c} for c, d in b] for a, b in itertools.groupby(new_d, key=lambda x:x[0]['id'])]
import json
print(json.dumps(result, indent=4))
Output:
[
[
{
"key1": "value1",
"key2": {
"id": 1,
"name": "name1"
}
},
{
"key1": "value1",
"key2": {
"id": 1,
"name": "name1"
}
},
{
"key1": "value1",
"key2": {
"id": 1,
"name": "name1"
}
}
],
[
{
"key1": "value1",
"key2": {
"id": 2,
"name": "name2"
}
}
],
[
{
"key1": "value1",
"key2": {
"id": 3,
"name": "name3"
}
}
]
]
Upvotes: 1
Reputation: 13413
I'm not sure why exactly ids 2 and 3 stayed together.
here's a version that groups by individual inner dicts (those with id
),
I'm not sure if that's helpful or by which logic you group the dicts later on, if you help me wrap my head around it maybe I can help get you desired output:
from itertools import groupby
from pprint import pprint
original = [
{'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}, {'id': 2, 'name': 'name2'}, {'id': 3, 'name': 'name3'}]},
{'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}, ]},
{'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}, ]}
]
keyfunc = lambda x: x['key2'][0]['id']
flattened_and_sorted_by_key2 = sorted([{'key1': d['key1'], 'key2':[inner_d]} for d in original for inner_d in d['key2']], key=keyfunc)
grouped_flattened = [list(x) for _, x in groupby(flattened_and_sorted_by_key2, key=keyfunc)]
pprint(grouped_flattened, indent=2)
this outputs 3 groups, one for each value of id
:
[ [ {'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}]},
{'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}]},
{'key1': 'value1', 'key2': [{'id': 1, 'name': 'name1'}]}],
[{'key1': 'value1', 'key2': [{'id': 2, 'name': 'name2'}]}],
[{'key1': 'value1', 'key2': [{'id': 3, 'name': 'name3'}]}]]
Upvotes: 3