I want to generate a dictionary from a list of dictionaries, grouping list items by the value of some key, such as:
input_list = [
{'a':'tata', 'b': 'foo'},
{'a':'pipo', 'b': 'titi'},
{'a':'pipo', 'b': 'toto'},
{'a':'tata', 'b': 'bar'}
]
output_dict = {
'pipo': [
{'a': 'pipo', 'b': 'titi'},
{'a': 'pipo', 'b': 'toto'}
],
'tata': [
{'a': 'tata', 'b': 'foo'},
{'a': 'tata', 'b': 'bar'}
]
}
So far I've found two ways of doing this. The first simply iterates over the list, create sublists in the dict for each key value and append elements matching these keys to the sublist:
l = [
{'a':'tata', 'b': 'foo'},
{'a':'pipo', 'b': 'titi'},
{'a':'pipo', 'b': 'toto'},
{'a':'tata', 'b': 'bar'}
]
res = {}
for e in l:
res[e['a']] = res.get[e['a'], []]
res[e['a']].append[e]
And another using itertools.groupby
:
import itertools
from operator import itemgetter
l = [
{'a':'tata', 'b': 'foo'},
{'a':'pipo', 'b': 'titi'},
{'a':'pipo', 'b': 'toto'},
{'a':'tata', 'b': 'bar'}
]
l = sorted[l, key=itemgetter['a']]
res = dict[[k, list[g]] for k, g in itertools.groupby[l, key=itemgetter['a']]]
I wonder which alternative is the most efficient?
Is there any more pythonic/concise or better performing way of achieving this?
View Discussion
Improve Article
Save Article
View Discussion
Improve Article
Save Article
Sometimes, while working with data, we can be encountered with a situation in which we have list of list and we need to group it’s 2nd index with the common initial element in lists. Let’s discuss way in which this problem can be solved.
Method : Using defaultdict[]
+ loop + dict[]
The defaultdict can be used to initialize the group elements and loop can be used to group the values together and conversion to dictionary can be done using dict[]
.
from
collections
import
defaultdict
test_list
=
[[
'Gfg'
,
1
], [
'Gfg'
,
2
], [
'is'
,
3
], [
'best'
,
4
], [
'is'
,
5
]]
print
[
"The original list is : "
+
str
[test_list]]
temp
=
defaultdict[
list
]
for
key, val
in
test_list:
temp[key].append[val]
res
=
dict
[[key,
tuple
[val]]
for
key, val
in
temp.items[]]
print
[
"The grouped dictionary is : "
+
str
[res]]
Output :
The original list is : [['Gfg', 1], ['Gfg', 2], ['is', 3], ['best', 4], ['is', 5]] The grouped dictionary is : {'Gfg': [1, 2], 'best': [4, ], 'is': [3, 5]}
Group List of Dictionary Data by Particular Key in Python can be done using itertools.groupby[] method.
Itertools.groupby[]
This method calculates the keys for each element present in iterable. It returns key and iterable of grouped items.
Syntax: itertools.groupby[iterable, key_func]
Parameters:
- iterable: Iterable can be of any kind [list, tuple, dictionary].
- key_func: A function that calculates keys for each element present in iterable.
Return type: It returns consecutive keys and groups from the iterable. If the key function is not specified or is None, key defaults to an identity function and returns the element unchanged.
Let’s see the examples: Example 1: Suppose we have list of dictionary of employee and company.
INFO = [ {'employee': 'XYZ_1', 'company': 'ABC_1'}, {'employee': 'XYZ_2', 'company': 'ABC_2'}, {'employee': 'XYZ_3', 'company': 'ABC_3'}, {'employee': 'XYZ_4', 'company': 'ABC_3'}, {'employee': 'XYZ_5', 'company': 'ABC_2'}, {'employee': 'XYZ_6', 'company': 'ABC_3'}, {'employee': 'XYZ_7', 'company': 'ABC_1'}, {'employee': 'XYZ_8', 'company': 'ABC_2'}, {'employee': 'XYZ_9', 'company': 'ABC_1'} ]
Now we need to display all the data group by the ‘company’ key name.
Code:
Python3
from
itertools
import
groupby
INFO
=
[
{
'employee'
:
'XYZ_1'
,
'company'
:
'ABC_1'
},
{
'employee'
:
'XYZ_2'
,
'company'
:
'ABC_2'
},
{
'employee'
:
'XYZ_3'
,
'company'
:
'ABC_3'
},
{
'employee'
:
'XYZ_4'
,
'company'
:
'ABC_3'
},
{
'employee'
:
'XYZ_5'
,
'company'
:
'ABC_2'
},
{
'employee'
:
'XYZ_6'
,
'company'
:
'ABC_3'
},
{
'employee'
:
'XYZ_7'
,
'company'
:
'ABC_1'
},
{
'employee'
:
'XYZ_8'
,
'company'
:
'ABC_2'
},
{
'employee'
:
'XYZ_9'
,
'company'
:
'ABC_1'
}
]
def
key_func[k]:
return
k[
'company'
]
INFO
=
sorted
[INFO, key
=
key_func]
for
key, value
in
groupby[INFO, key_func]:
print
[key]
print
[
list
[value]]
Output:
ABC_1 [{’employee’: ‘XYZ_1’, ‘company’: ‘ABC_1′}, {’employee’: ‘XYZ_7’, ‘company’: ‘ABC_1′}, {’employee’: ‘XYZ_9’, ‘company’: ‘ABC_1′}] ABC_2 [{’employee’: ‘XYZ_2’, ‘company’: ‘ABC_2′}, {’employee’: ‘XYZ_5’, ‘company’: ‘ABC_2′}, {’employee’: ‘XYZ_8’, ‘company’: ‘ABC_2′}] ABC_3 [{’employee’: ‘XYZ_3’, ‘company’: ‘ABC_3′}, {’employee’: ‘XYZ_4’, ‘company’: ‘ABC_3′}, {’employee’: ‘XYZ_6’, ‘company’: ‘ABC_3’}]
Example 2: Suppose we have list of dictionary of student grades and marks.
students = [ {'mark': '65','grade': 'C'}, {'mark': '86','grade': 'A'}, {'mark': '73','grade': 'B'}, {'mark': '49','grade': 'D'}, {'mark': '91','grade': 'A'}, {'mark': '79','grade': 'B'} ]
Now we need to display all the data group by the ‘grade’ key.
Code:
Python3
from
itertools
import
groupby
from
operator
import
itemgetter
students
=
[
{
'mark'
:
'65'
,
'grade'
:
'C'
},
{
'mark'
:
'86'
,
'grade'
:
'A'
},
{
'mark'
:
'73'
,
'grade'
:
'B'
},
{
'mark'
:
'49'
,
'grade'
:
'D'
},
{
'mark'
:
'91'
,
'grade'
:
'A'
},
{
'mark'
:
'79'
,
'grade'
:
'B'
}
]
students
=
sorted
[students,
key
=
itemgetter[
'grade'
]]
for
key, value
in
groupby[students,
key
=
itemgetter[
'grade'
]]:
print
[key]
for
k
in
value:
print
[k]
Output:
A {'mark': '86', 'grade': 'A'} {'mark': '91', 'grade': 'A'} B {'mark': '73', 'grade': 'B'} {'mark': '79', 'grade': 'B'} C {'mark': '65', 'grade': 'C'} D {'mark': '49', 'grade': 'D'}