Group python list of dictionaries by values - python

Given I have a list of dictionaries I want to create new list of lists grouping the dictionaries by the values of "price":
dicts = [
{ "name": "item1", "price": 10 },
{ "name": "item2", "price": 5 },
{ "name": "item3", "price": 10 },
{ "name": "item4", "price": 12 },
{ "name": "item5", "price": 12 },
{ "name": "item6", "price": 5 }
]
Should create:
grouped_dicts = [
[{ "name": "item1", "price": 10 },
{ "name": "item3", "price": 10 }],
[{ "name": "item2", "price": 5 },
{ "name": "item6", "price": 5 }],
[{ "name": "item4", "price": 12 },
{ "name": "item5", "price": 12 }]
]
Is there a nice way of doing this?
Thanks

As an alternative to the answer above, here is how you do it without an additional import:
d = {}
for item in dicts:
d.setdefault(item['price'], []).append(item)
list(d.values())
Out:
[[{'name': 'item1', 'price': 10}, {'name': 'item3', 'price': 10}],
[{'name': 'item2', 'price': 5}, {'name': 'item6', 'price': 5}],
[{'name': 'item4', 'price': 12}, {'name': 'item5', 'price': 12}]]

You could use deaultdict
from collections import defaultdict
d=defaultdict(list)
for item in dicts:
d[list(item.values())[-1]].append(item)
Output:
defaultdict(list,
{10: [{'name': 'item1', 'price': 10},
{'name': 'item3', 'price': 10}],
5: [{'name': 'item2', 'price': 5}, {'name': 'item6', 'price': 5}],
12: [{'name': 'item4', 'price': 12},
{'name': 'item5', 'price': 12}]})
If you just need the list then just extract the values of defaultdict
list(d.values())
Output:
[[{'name': 'item1', 'price': 10}, {'name': 'item3', 'price': 10}],
[{'name': 'item2', 'price': 5}, {'name': 'item6', 'price': 5}],
[{'name': 'item4', 'price': 12}, {'name': 'item5', 'price': 12}]]

Related

How to convert list of multiple jsons into individual jsons using pyspark

I have a list of jsons as mentioned below
[
{
"files": 0,
"data": [
{"name": "RFC", "value": "XXXXXXX", "attId": 01},
{"name": "NOMBRE", "value": "JOSE", "attId": 02},
{"name": "APELLIDO PATERNO", "value": "MONTIEL", "attId": 03},
{"name": "APELLIDO MATERNO", "value": "MENDOZA", "attId": 04},
{"name": "FECHA NACIMIENTO", "value": "1989-02-04", "attId": 05}
],
"dirId": 1,
"docId": 4,
"structure": {
"name": "personales",
"folioId": 22
}
},
{
"files": 0,
"data": [
{"name": "CALLE", "value": "AMOR", "attId": 06},
{"name": "No. EXTERIOR", "value": "4", "attId": 07},
{"name": "No. INTERIOR", "value": "2", "attId": 08},
{"name": "C.P.", "value": "55060", "attId": 09},
{"name": "ENTIDAD", "value": "ESTADO DE MEXICO", "attId": 10},
{"name": "MUNICIPIO", "value": "ECATEPEC", "attId": 11},
{"name": "COLONIA", "value": "INDUSTRIAL", "attId": 12}
],
"dirId": 1,
"docId": 4,
"structure": {
"name": "direccion",
"folioId": 22
}
}
]
I need to convert this list of jsons into separate individual jsons and execute them separately.
how to achieve this using pyspark or python?
Something like this, just one loop should work;
PN: There are few leading zeros in your input raw data...
# Assuming given list in your question is stored in lst
for item in lst:
print(item,"\n")
# item here will behave as individual dict/json
# Do your coding here as required
# Output for items;
{'files': 0, 'data': [{'name': 'RFC', 'value': 'XXXXXXX', 'attId': '01'}, {'name': 'NOMBRE', 'value': 'JOSE', 'attId': '02'}, {'name': 'APELLIDO PATERNO', 'value': 'MONTIEL', 'attId': '03'}, {'name': 'APELLIDO MATERNO', 'value': 'MENDOZA', 'attId': '04'}, {'name': 'FECHA NACIMIENTO', 'value': '1989-02-04', 'attId': '05'}], 'dirId': 1, 'docId': 4, 'structure': {'name': 'personales', 'folioId': 22}}
{'files': 0, 'data': [{'name': 'CALLE', 'value': 'AMOR', 'attId': '06'}, {'name': 'No. EXTERIOR', 'value': '4', 'attId': '07'}, {'name': 'No. INTERIOR', 'value': '2', 'attId': '08'}, {'name': 'C.P.', 'value': '55060', 'attId': '09'}, {'name': 'ENTIDAD', 'value': 'ESTADO DE MEXICO', 'attId': '10'}, {'name': 'MUNICIPIO', 'value': 'ECATEPEC', 'attId': '11'}, {'name': 'COLONIA', 'value': 'INDUSTRIAL', 'attId': '12'}], 'dirId': 1, 'docId': 4, 'structure': {'name': 'direccion', 'folioId': 22}}

How to add data to dictionary from an array conditionally

I have dictionaries in a list that already have some data and I want to add a vin number to each brand in these dictionaries.
my_brand_dict = [
{"key": {"Brand": "Tesla", "Date": "20203"}, "Total": 56},
{"key": {"Brand": "Tesla", "Date": "20207"}, "Total": 88},
{"key": {"Brand": "Audi", "Date": "202014"}, "Total": 79},
{"key": {"Brand": "Mercedes", "Date": "20201"}, "Total": 49},
]
my_vins = ["f60a0a", "#2019c0", "#a81b1b", "#468650", "#21248a", "#ff7a00"]
When Brand is Tesla add '#468650'
When Brand is Mercedes add '#2019c0'
When Brand is Toyota add '#21248a'
When Brand is Audi add '#ff7a00'
My expected output:
my_brand_dict = [
{"key": {"Brand": "Tesla", "Date": "20203"}, "Total": 56, "my_vin": "#468650"},
{"key": {"Brand": "Toyota", "Date": "20207"}, "Total": 88, "my_vin": "#21248a"},
{"key": {"Brand": "Audi", "Date": "202014"}, "Total": 79, "my_vin": "#ff7a00"},
{"key": {"Brand": "Mercedes", "Date": "20201"}, "Total": 49, "my_vin": "#2019c0"},
]
Couldn't find anything that matches what I want to achieve
Conditionally add values to dictionary
I would suggest using a dictionary instead of a list for your my_vins so that it maps brands to vins. This way you can easily get corresponding vin.
my_brand_dict = [
{"key": {"Brand": "Tesla", "Date": "20203"}, "Total": 56},
{"key": {"Brand": "Tesla", "Date": "20207"}, "Total": 88},
{"key": {"Brand": "Audi", "Date": "202014"}, "Total": 79},
{"key": {"Brand": "Mercedes", "Date": "20201"}, "Total": 49},
]
my_vins = {
"Mercedes": "#2019c0",
"Tesla": "#468650",
"Toyota": "#21248a",
"Audi": "#ff7a00",
}
for d in my_brand_dict:
brand = d["key"]["Brand"]
vin = my_vins[brand]
d["my_vin"] = vin
print(my_brand_dict)
Then take care of what should happen if a brand doesn't have a vin, You can raise exception or assign a default value.
You can define a dict base Brand & my_vins. Then use the defined dict and change value in-place in the my_brand_dict like the below.
my_vins_dct = {'Tesla' : '#468650',
'Mercedes' : '#2019c0',
'Toyota' : '#21248a',
'Audi' : '#ff7a00'}
my_brand_dict = [
{"key": {"Brand": "Tesla", "Date": "20203"}, "Total": 56},
{"key": {"Brand": "Tesla", "Date": "20207"}, "Total": 88},
{"key": {"Brand": "Audi", "Date": "202014"}, "Total": 79},
{"key": {"Brand": "Mercedes", "Date": "20201"}, "Total": 49},
{"key": {"Brand": "xxxx", "Date": "20201"}, "Total": 49},
]
for dct in my_brand_dict:
# First approach try/except and 'continue'
try :
dct['my_vin'] = my_vins_dct[dct['key']['Brand']]
except KeyError:
continue
# Second approach for adding 'Not Found'
# dct['my_vin'] = my_vins_dct.get(dct['key']['Brand'], 'Brand Not Found')
print(my_brand_dict)
Output:
[
{'key': {'Brand': 'Tesla', 'Date': '20203'}, 'Total': 56, 'my_vin': '#468650'},
{'key': {'Brand': 'Tesla', 'Date': '20207'}, 'Total': 88, 'my_vin': '#468650'},
{'key': {'Brand': 'Audi', 'Date': '202014'}, 'Total': 79, 'my_vin': '#ff7a00'},
{'key': {'Brand': 'Mercedes', 'Date': '20201'}, 'Total': 49, 'my_vin': '#2019c0'},
{'key': {'Brand': 'xxxx', 'Date': '20201'}, 'Total': 49}
]
# Output Second approach
# [
# {'key': {'Brand': 'Tesla', 'Date': '20203'}, 'Total': 56, 'my_vin': '#468650'},
# {'key': {'Brand': 'Tesla', 'Date': '20207'}, 'Total': 88, 'my_vin': '#468650'},
# {'key': {'Brand': 'Audi', 'Date': '202014'}, 'Total': 79, 'my_vin': '#ff7a00'},
# {'key': {'Brand': 'Mercedes', 'Date': '20201'}, 'Total': 49, 'my_vin': '#2019c0'},
# {'key': {'Brand': 'xxxx', 'Date': '20201'}, 'Total': 49, 'my_vin': 'Brand Not Found'}
# ]
my_brand_dict = [{'key': {'Brand': 'Tesla', 'Date': '20203'}, 'Total': 56}, {'key': {'Brand': 'Tesla', 'Date': '20207'}, 'Total': 88},
{'key': {'Brand': 'Audi', 'Date': '202014'}, 'Total': 79}, {'key': {'Brand': 'Mercedes', 'Date': '20201'}, 'Total': 49}]
my_vins = ['f60a0a', '#2019c0', '#a81b1b', '#468650', '#21248a', '#ff7a00']
# When Brand Tesla add '#468650'
# When Brand Mercedes add '#2019c0'
# When Brand Toyota add '#21248a'
# When Brand Audi add '#ff7a00'
for item in my_brand_dict:
if item['key']['Brand'] == 'Tesla':
item['my_vin'] = '#468650'
elif item['key']['Brand'] == 'Mercedes':
item['my_vin'] = '#2019c0'
elif item['key']['Brand'] == 'Toyota':
item['my_vin'] = '#21248a'
elif item['key']['Brand'] == 'Audi':
item['my_vin'] = '#ff7a00'
print(my_brand_dict)
This code works for me

Convert list of dictionaries into a nested dictionary [duplicate]

This question already has answers here:
Python: create a nested dictionary from a list of parent child values
(3 answers)
Closed 3 years ago.
I have a list of dictionaries that I got from the database in parent-child relationship:
data = [
{"id":1, "parent_id": 0, "name": "Wood", "price": 0},
{"id":2, "parent_id": 1, "name": "Mango", "price": 18},
{"id":3, "parent_id": 2, "name": "Table", "price": 342},
{"id":4, "parent_id": 2, "name": "Box", "price": 340},
{"id":5, "parent_id": 4, "name": "Pencil", "price": 240},
{"id":6, "parent_id": 0, "name": "Electronic", "price": 20},
{"id":7, "parent_id": 6, "name": "TV", "price": 350},
{"id":8, "parent_id": 6, "name": "Mobile", "price": 300},
{"id":9, "parent_id": 8, "name": "Iphone", "price": 0},
{"id":10, "parent_id": 9, "name": "Iphone 10", "price": 400}
]
I want to convert it to a nested dictionary such as
[ { "id": 1, "parent_id": 0, "name": "Wood", "price": 0, "children": [ { "id": 2, "parent_id": 1, "name": "Mango", "price": 18, "children": [ { "id": 3, "parent_id": 2, "name": "Table", "price": 342 }, { "id": 4, "parent_id": 2, "name": "Box", "price": 340, "children": [ { "id": 5, "parent_id": 4, "name": "Pencil", "price": 240 } ] } ] } ] }, { "id": 6, "parent_id": 0, "name": "Electronic", "price": 20, "children": [ { "id": 7, "parent_id": 6, "name": "TV", "price": 350 }, { "id": 8, "parent_id": 6, "name": "Mobile", "price": 300, "children": [ { "id": 9, "parent_id": 8, "name": "Iphone", "price": 0, "children": [ { "id": 10, "parent_id": 9, "name": "Iphone 10", "price": 400 } ] } ] } ] } ]
You can do this recursively, starting from the root nodes (where parent_id = 0) going downwards. But before your recursive calls, you can group nodes by their parent_id so that accessing them in each recursive call can be done in constant time:
levels = {}
for n in data:
levels.setdefault(n['parent_id'], []).append(n)
def build_tree(parent_id=0):
nodes = [dict(n) for n in levels.get(parent_id, [])]
for n in nodes:
children = build_tree(n['id'])
if children: n['children'] = children
return nodes
tree = build_tree()
print(tree)
Output
[{'id': 1, 'parent_id': 0, 'name': 'Wood', 'price': 0, 'children': [{'id': 2, 'parent_id': 1, 'name': 'Mango', 'price': 18, 'children': [{'id': 3, 'parent_id': 2, 'name': 'Table', 'price': 342}, {'id': 4, 'parent_id': 2, 'name': 'Box', 'price': 340, 'children': [{'id': 5, 'parent_id': 4, 'name': 'Pencil', 'price': 240}]}]}]}, {'id': 6, 'parent_id': 0, 'name': 'Electronic', 'price': 20, 'children': [{'id': 7, 'parent_id': 6, 'name': 'TV', 'price': 350}, {'id': 8, 'parent_id': 6, 'name': 'Mobile', 'price': 300, 'children': [{'id': 9, 'parent_id': 8, 'name': 'Iphone', 'price': 0,'children': [{'id': 10, 'parent_id': 9, 'name': 'Iphone 10', 'price': 400}]}]}]}]
Code is documented inline. Ignoring the corner cases like circular relations etc.
# Actual Data
data = [
{"id":1, "parent_id": 0, "name": "Wood", "price": 0},
{"id":2, "parent_id": 1, "name": "Mango", "price": 18},
{"id":3, "parent_id": 2, "name": "Table", "price": 342},
{"id":4, "parent_id": 2, "name": "Box", "price": 340},
{"id":5, "parent_id": 4, "name": "Pencil", "price": 240},
{"id":6, "parent_id": 0, "name": "Electronic", "price": 20},
{"id":7, "parent_id": 6, "name": "TV", "price": 350},
{"id":8, "parent_id": 6, "name": "Mobile", "price": 300},
{"id":9, "parent_id": 8, "name": "Iphone", "price": 0},
{"id":10, "parent_id": 9, "name": "Iphone 10", "price": 400}
]
# Create Parent -> child links using dictonary
data_dict = { r['id'] : r for r in data}
for r in data:
if r['parent_id'] in data_dict:
parent = data_dict[r['parent_id']]
if 'children' not in parent:
parent['children'] = []
parent['children'].append(r)
# Helper function to get all the id's associated with a parent
def get_all_ids(r):
l = list()
l.append(r['id'])
if 'children' in r:
for c in r['children']:
l.extend(get_all_ids(c))
return l
# Trimp the results to have a id only once
ids = set(data_dict.keys())
result = []
for r in data_dict.values():
the_ids = set(get_all_ids(r))
if ids.intersection(the_ids):
ids = ids.difference(the_ids)
result.append(r)
print (result)
Output:
[{'id': 1, 'parent_id': 0, 'name': 'Wood', 'price': 0, 'children': [{'id': 2, 'parent_id': 1, 'name': 'Mango', 'price': 18, 'children': [{'id': 3, 'parent_id': 2, 'name': 'Table', 'price': 342}, {'id': 4, 'parent_id': 2, 'name': 'Box', 'price': 340, 'children': [{'id': 5, 'parent_id': 4, 'name': 'Pencil', 'price': 240}]}]}]}, {'id': 6, 'parent_id': 0, 'name': 'Electronic', 'price': 20, 'children': [{'id': 7, 'parent_id': 6, 'name': 'TV', 'price': 350}, {'id': 8, 'parent_id': 6, 'name': 'Mobile', 'price': 300, 'children': [{'id': 9, 'parent_id': 8, 'name': 'Iphone', 'price': 0, 'children': [{'id': 10, 'parent_id': 9, 'name': 'Iphone 10', 'price': 400}]}]}]}]
I worked out a VERY SHORT solution, I believe it isn't the most efficient algorithm, but it does the job, will need a hell of optimization to work on very large data sets.
for i in range(len(data)-1, -1, -1):
data[i]["children"] = [child for child in data if child["parent_id"] == data[i]["id"]]
for child in data[i]["children"]:
data.remove(child)
Here is the complete explanation:
data = [
{"id":1, "parent_id": 0, "name": "Wood", "price": 0},
{"id":2, "parent_id": 1, "name": "Mango", "price": 18},
{"id":3, "parent_id": 2, "name": "Table", "price": 342},
{"id":4, "parent_id": 2, "name": "Box", "price": 340},
{"id":5, "parent_id": 4, "name": "Pencil", "price": 240},
{"id":6, "parent_id": 0, "name": "Electronic", "price": 20},
{"id":7, "parent_id": 6, "name": "TV", "price": 350},
{"id":8, "parent_id": 6, "name": "Mobile", "price": 300},
{"id":9, "parent_id": 8, "name": "Iphone", "price": 0},
{"id":10, "parent_id": 9, "name": "Iphone 10", "price": 400}
]
# Looping backwards,placing the lowest child
# into the next parent in the heirarchy
for i in range(len(data)-1, -1, -1):
# Create a dict key for the current parent in the loop called "children"
# and assign to it a list comprehension that loops over all items in the data
# to get the elements which have a parent_id equivalent to our current element's id
data[i]["children"] = [child for child in data if child["parent_id"] == data[i]["id"]]
# since the child is placed inside our its parent already, we will
# remove it from its actual position in the data
for child in data[i]["children"]:
data.remove(child)
# print the new data structure
print(data)
And here is the output:
[{'id': 1, 'parent_id': 0, 'name': 'Wood', 'price': 0, 'children': [{'id': 2, 'parent_id': 1, 'name': 'Mango', 'price': 18, 'children': [{'id': 3, 'parent_id': 2, 'name': 'Table', 'price': 342, 'children': []}, {'id': 4, 'parent_id': 2, 'name': 'Box', 'price': 340, 'children': [{'id': 5, 'parent_id': 4, 'name': 'Pencil', 'price': 240, 'children': []}]}]}]}, {'id': 6, 'parent_id': 0, 'name': 'Electronic', 'price': 20, 'children': [{'id': 7, 'parent_id': 6, 'name': 'TV', 'price': 350, 'children': []}, {'id': 8, 'parent_id': 6, 'name': 'Mobile', 'price': 300, 'children': [{'id': 9, 'parent_id': 8, 'name': 'Iphone', 'price': 0, 'children': [{'id': 10, 'parent_id': 9, 'name': 'Iphone 10', 'price': 400, 'children': []}]}]}]}]

Python, reorganize array of dicts

To be honest, it's too easy for me to make in JS or Perl, but i've completely stuck with that in Python because of coplexed tools for dealing with dicts/lists. So, what i need:
i have an array of dicts:
[
{"id": 1, "name": "Res1", "type": "resource", "k_name": "Ind1_1", "k_id": 4},
{"id": 1, "name": "Res1", "type": "resource", "k_name": "Ind1_2", "k_id": 5},
{"id": 1, "name": "Res1", "type": "resource", "k_name": "Ind1_3", "k_id": 6},
{"id": 2, "name": "Res2", "type": "service", "k_name": "Ind2_1", "k_id": 7},
{"id": 2, "name": "Res2", "type": "service", "k_name": "Ind2_2", "k_id": 8},
{"id": 2, "name": "Res2", "type": "service", "k_name": "Ind2_3", "k_id": 9},
{"id": 2, "name": "Res2", "type": "service", "k_name": "Ind2_4", "k_id": 10},
{"id": 3, "name": "Res3", "type": "service", "k_name": "Ind3_1", "k_id": 11},
{"id": 3, "name": "Res3", "type": "service", "k_name": "Ind3_2", "k_id": 12},
{"id": 3, "name": "Res3", "type": "service", "k_name": "Ind3_3", "k_id": 13},
{"id": 3, "name": "Res3", "type": "service", "k_name": "Ind3_4", "k_id": 14}
]
and i need to make that:
[
{
"id": 1,
"name": "Res1",
"type": "resource",
"indicators": [
{"name": "Ind1_1","id": 4},
{"name": "Ind1_2","id": 5},
{"name": "Ind1_3","id": 6}
]
},
{
"id": 2,
"name": "Res2",
"type": "service",
"indicators": [
{"name": "Ind2_1","id": 7},
{"name": "Ind2_2","id": 8},
{"name": "Ind2_3","id": 9},
{"name": "Ind2_4","id": 10}
]
},
{
"id": 3,
"name": "Res3",
"type": "service",
"indicators": [
{"name": "Ind3_1","id": 11},
{"name": "Ind3_2","id": 12},
{"name": "Ind3_3","id": 13},
{"name": "Ind3_4","id": 14}
]
}
]
Can you help me with that?
itertools to the rescue:
import itertools
# Assuming your original list is `l`
# if it does not come in order, you need to do this line first, and will probably be less efficient.
l = sorted(l, key=lambda x:(x["id"], x["name"], x["type"]))
d = []
for k, g in itertools.groupby(l, lambda x: (x["id"], x["name"], x["type"])):
d.append({i:v for i, v in zip(["id", "name", "type"], k)})
d[-1]["indicator"] = [{y.split('_')[1]:e[y] for y in ["k_id", "k_name"]} for e in list(g)]
d becomes:
[{'id': 1,
'indicator': [{'id': 4, 'name': 'Ind1_1'},
{'id': 5, 'name': 'Ind1_2'},
{'id': 6, 'name': 'Ind1_3'}],
'name': 'Res1',
'type': 'resource'},
{'id': 2,
'indicator': [{'id': 7, 'name': 'Ind2_1'},
{'id': 8, 'name': 'Ind2_2'},
{'id': 9, 'name': 'Ind2_3'},
{'id': 10, 'name': 'Ind2_4'}],
'name': 'Res2',
'type': 'service'},
{'id': 3,
'indicator': [{'id': 11, 'name': 'Ind3_1'},
{'id': 12, 'name': 'Ind3_2'},
{'id': 13, 'name': 'Ind3_3'},
{'id': 14, 'name': 'Ind3_4'}],
'name': 'Res3',
'type': 'service'}]
You can use a mapping dict to map ids to corresponding sub-lists, so that as you iterate through the list (named l in this example), you can append a new entry to the output list if the id is not found in the mapping, or append the entry to the existing sub-list if id is found in the mapping:
mapping = {}
output = []
for d in l:
i = {'name': d.pop('k_name'), 'id': d.pop('k_id')}
if d['id'] in mapping:
mapping[d['id']].append(i)
else:
output.append({**d, 'indicators': [i]})
mapping[d['id']] = output[-1]['indicators']
output becomes:
[{'id': 1, 'name': 'Res1', 'type': 'resource', 'indicators': [{'name': 'Ind1_1', 'id': 4}, {'name': 'Ind1_2', 'id': 5}, {'name': 'Ind1_3', 'id': 6}]}, {'id': 2, 'name': 'Res2', 'type': 'service', 'indicators': [{'name': 'Ind2_1', 'id': 7}, {'name': 'Ind2_2', 'id': 8}, {'name': 'Ind2_3', 'id': 9}, {'name': 'Ind2_4', 'id': 10}]}, {'id': 3, 'name': 'Res3', 'type': 'service', 'indicators': [{'name': 'Ind3_1', 'id': 11}, {'name': 'Ind3_2', 'id': 12}, {'name': 'Ind3_3', 'id': 13}, {'name': 'Ind3_4', 'id': 14}]}]

I am working with python3, where i have list of dictionaries

I have following list of dictionaries which contains job_name,count and city name
question = [{
"count": 2,
"city": "Pune",
"job_NAME": "clerk"
}, {
"count": 1,
"city": "kolkata",
"job_NAME": "manager"
}, {
"count": 2,
"city": "Mumbai",
"job_NAME": "accountant"
}, {
"count": 1,
"city": "New Delhi",
"job_NAME": "clerk"
}]
what i want is if job_name is same in this case "clerk" the count and city has to be in one list under key "jobs"
answer = [{
"job_name": "clerk",
"jobs": [{
"city": "pune",
"count": 2
}, {
"city": "New Delhi",
"count": 1
}]
}, {
"job_name": "manager",
"jobs": [{
"city": "kolkata",
"count": 1
}]
}, {
"job_name": "accountant",
"jobs": [{
"city": "Mumbai",
"count": 2
}]
}]
if there is any job duplicate job profile in question list in this case clerk its city and count should be appended in "jobs" key list.
i would be very grateful for any help provided!
Thanks in advance
Using collections.defaultdict
Ex:
from collections import defaultdict
d = defaultdict(list)
question = [{'count': 2, 'city': 'Pune', 'job_NAME': 'clerk'}, {'count': 1, 'city': 'kolkata', 'job_NAME': 'manager'}, {'count': 2, 'city': 'Mumbai', 'job_NAME': 'accountant'}, {'count': 1, 'city': 'New Delhi', 'job_NAME': 'clerk'}]
for i in question:
d[i["job_NAME"]].append({"city": i["city"], "count": i["count"]})
answer = [{"job_name": k, "jobs": v} for k, v in d.items()]
print(answer)
Output:
[{'job_name': 'clerk',
'jobs': [{'city': 'Pune', 'count': 2}, {'city': 'New Delhi', 'count': 1}]},
{'job_name': 'accountant', 'jobs': [{'city': 'Mumbai', 'count': 2}]},
{'job_name': 'manager', 'jobs': [{'city': 'kolkata', 'count': 1}]}]
I use defaultdict(list) to group the entries from the input list first and then in a second iteration I setup the result:
from collections import defaultdict
groups = defaultdict(list)
for jobs in question:
job_name = jobs["job_NAME"]
del jobs["job_NAME"]
groups[job_name].append(jobs)
answer = [
dict(job_name=job_name, jobs=jobs) for job_name, jobs in groups.items()
]
# alternative with classic loop
answer = []
for job_name, jobs in groups.items():
answer.append(dict(job_name=job_name, jobs=jobs))
One-liner:
from itertools import groupby
from operator import itemgetter
answer = [{'job_name': k, 'jobs': [{f: v for f, v in d.items() if f != 'job_NAME'} for d in g]}
for k, g in groupby(sorted(question, key=itemgetter('job_NAME')), key=itemgetter('job_NAME'))]
Result:
[{'job_name': 'accountant', 'jobs': [{'count': 2, 'city': 'Mumbai'}]},
{'job_name': 'clerk',
'jobs': [{'count': 2, 'city': 'Pune'}, {'count': 1, 'city': 'New Delhi'}]},
{'job_name': 'manager', 'jobs': [{'count': 1, 'city': 'kolkata'}]}]
Sort and group question by job_NAME and then just construct answer as list of dicts with job_name and jobs.

Categories

Resources