i have a simple task but not able to figure it out.
a = [{'name': 'Helen', 'age': '12', 'total_money':'12000'}, {'name': 'Victor', 'age':'20', 'total_money': '32999'}]
b = [{'name': 'Helen', 'age': '12', 'total_gold':'14'}]
I want to mere to list above, if the value of name and ageis the same then combine it together. if not the same then leave it as it is.
expected output
output = [{'name': 'Helen', 'age': '12', 'total_money':'12000', 'total_gold':'14'}, {'name': 'Victor', 'age':'20', 'total_money': '32999'}]
this is what i have tried so far (not working)
c = a + b
data = {}
for item in c:
key = item["name"]+'-'+item["age"]
if key in data:
if data[key]["total_money"] in data[key]:
data[key]["total_gold"] = item["total_gold"]
else:
data[key]["total_money"] = item["total_money"]
else:
data[key] = item
data[key]["total_money"] = item['total_money'] if 'total_money' in item else 0
data[key]["total_gold"] = item['total_gold'] if 'total_gold' in item else 0
i have a feeling that i am overthinking. any suggestion would be appreciate. Thank you.
Seems like you want to merge two dictionaries, which can be done like so:
a = {'name': 'Helen', 'age': '12', 'total_money':'12000'}
b = {'name': 'Helen', 'age': '12', 'total_gold':'14'}
z = {**a, **b}
z
{'name': 'Helen', 'age': '12', 'total_money': '12000', 'total_gold': '14'}
If you'd like to maintain the list structure (assuming you plan to have multiple dictionaries as elements of these lists):
a = [{'name': 'Helen', 'age': '12', 'total_money':'12000'}]
b = [{'name': 'Helen', 'age': '12', 'total_gold':'14'}]
z = []
for i in range(len(a)):
z.append({**a[i], **b[i]})
EDIT:
z = []
for ele in a:
for piece in b:
if ele["name"] == piece["name"] and ele["age"] == piece["age"]:
z.append({**ele, **piece})
else:
z.append(ele)
Solution
This is a good opportunity to learn how to use itertools.groupby():
import itertools
def sort_help(d: dict) -> tuple:
return d["name"], d["age"]
merged = []
for _, group in itertools.groupby(sorted(a + b, key=sort_help), key=sort_help):
merged_dict = {}
for d in group:
merged_dict.update(d)
merged.append(merged_dict)
Output:
[{'name': 'Helen', 'age': '12', 'total_money': '12000', 'total_gold': '14'},
{'name': 'Victor', 'age': '20', 'total_money': '32999'}]
Explanation
This works by first concatenating your lists of dictionaries, and then sorting them by name, age tuples:
In [6]: a + b
Out[6]:
[{'name': 'Helen', 'age': '12', 'total_money': '12000'},
{'name': 'Victor', 'age': '20', 'total_money': '32999'},
{'name': 'Helen', 'age': '12', 'total_gold': '14'}]
In [7]: both_in_order = sorted(a + b, key=sort_help)
In [8]: both_in_order
Out[8]:
[{'name': 'Helen', 'age': '12', 'total_money': '12000'},
{'name': 'Helen', 'age': '12', 'total_gold': '14'},
{'name': 'Victor', 'age': '20', 'total_money': '32999'}]
Then groupby groups the dictionaries into groups of matching name, age tuples:
In [9]: for _, g in itertools.groupby(both_in_order, key=sort_help):
...: print(list(g))
...:
[{'name': 'Helen', 'age': '12', 'total_money': '12000'}, {'name': 'Helen', 'age': '12', 'total_gold': '14'}]
[{'name': 'Victor', 'age': '20', 'total_money': '32999'}]
From there, each group's dictionaries are merged into one.
Advantages
This method also has the benefit of being "extensible"; you could add more criteria for what dictionaries should merge by simply modifying the sort_help function:
[{'name': 'Victor', 'age': 30, 'occupation': 'farmer', 'total_money': 1871},
{'name': 'Helen', 'age': 30, 'occupation': 'adventurer', 'total_gold': 8026},
{'name': 'Helen', 'age': 30, 'occupation': 'farmer', 'total_money': 7279},
{'name': 'Victor', 'age': 20, 'occupation': 'farmer', 'total_gold': 9762},
{'name': 'Victor', 'age': 20, 'occupation': 'farmer', 'total_money': 2853},
{'name': 'Helen', 'age': 30, 'occupation': 'adventurer', 'total_gold': 6002},
{'name': 'Victor', 'age': 20, 'occupation': 'farmer', 'total_gold': 582},
{'name': 'Helen', 'age': 30, 'occupation': 'adventurer', 'total_money': 8632},
{'name': 'Victor', 'age': 30, 'occupation': 'adventurer', 'total_gold': 6528},
{'name': 'Helen', 'age': 30, 'occupation': 'adventurer', 'total_money': 4101}]
By adding "occupation" to sort_help(), we can very easily now group the dictionaries by all three criteria:
def sort_help(d: dict) -> tuple:
return d["name"], d["age"], d["occupation"]
Output:
[{'name': 'Helen', 'age': 30, 'occupation': 'adventurer', 'total_money': 4101, 'total_gold': 8026},
{'name': 'Helen', 'age': 30, 'occupation': 'farmer', 'total_money': 7279},
{'name': 'Victor', 'age': 20, 'occupation': 'farmer', 'total_gold': 9762, 'total_money': 2853},
{'name': 'Victor', 'age': 30, 'occupation': 'adventurer', 'total_gold': 6528},
{'name': 'Victor', 'age': 30, 'occupation': 'farmer', 'total_money': 1871}]
You can also very easily come up with a custom merging function which would, for example, add total_money instead of overwrite.
I re-wrote your function:
for item in c:
key = item["name"]+'-'+item["age"]
if key not in data:
data[key] = item
if "total_gold" in item:
data[key]["total_gold"] = item["total_gold"]
if "total_money" in item:
data[key]["total_money"] = item["total_money"]
if total_gold or total_money is written twice for the same "key" is will user the last value
output: [{'name': 'Helen', 'age': '12', 'total_money': '12000', 'total_gold': '14'}, {'name': 'Victor', 'age': '20', 'total_money': '32999'}]
just iterate over the dictionaries, creating a new dictionary with the values. if the value is a dup it will continue:
a = {'name': 'Helen', 'age': '12', 'total_money':'12000'}
b = {'name': 'Helen', 'age': '12', 'total_gold':'14'}
c={}
for k,v in a.items():
c[k]=v
for k,v in b.items():
c[k]=v
print(c)
#{'name': 'Helen', 'age': '12', 'total_money': '12000', 'total_gold': '14'}
This question already has answers here:
filtering dictionary based on value in a key [duplicate]
(2 answers)
Closed 2 years ago.
I would like to filter the dictionary that has 'hometown':'NY'
[{'name': 'paul', 'age': '26', 'hometown': '98_street_AU', 'gender': 'male'},
{'name': 'mei', 'age': '27', 'hometown': '19_street_NY', 'gender': 'female'},
{'name': 'smith', 'age': '14', 'hometown': '7_street_NY', 'gender': 'male'},
{'name': 'raj', 'age': '13', 'hometown': '56_street_IND', 'gender': 'male'},.....]
here is my code to filter the dictionary and the output
a=[]
for test in result:
x={}
for key,value in test.items():
if key == 'hometown':
if 'NY' in value:
x[key] = value
a.append(x)
print(a)
[{}, {'hometown': '19_street_NY'}, {'hometown': '7_street_NY'}, {}]
my desired output is
[{'name': 'mei', 'age': '27', 'hometown': '19_street_NY', 'gender': 'female'},
{'name': 'smith', 'age': '14', 'hometown': '7_street_NY', 'gender': 'male'}]
Try this simple method:
a=[]
for i in result:
if i['hometown'].__contains__("NY"):
a.append(i)
print(a)
Using a list comprehension with str.endswith
Ex:
a = [test for test in result if test.get('hometown', "").endswith('NY')]
You are adding only item hometown not the dictionary. This should work:
a=[]
for test in result:
x={}
for key,value in test.items():
if key == 'hometown':
if 'NY' in value:
a.append(test)
print(a)
In [6]: a = [{'name': 'paul', 'age': '26', 'hometown': '98_street_AU', 'gender': 'male'},
...: {'name': 'mei', 'age': '27', 'hometown': '19_street_NY', 'gender': 'female'},
...: {'name': 'smith', 'age': '14', 'hometown': '7_street_NY', 'gender': 'male'},
...: {'name': 'raj', 'age': '13', 'hometown': '56_street_IND', 'gender': 'male'}]
In [7]: [i for i in a if "hometown" in i and i["hometown"].endswith("NY")]
Out[7]:
[{'name': 'mei', 'age': '27', 'hometown': '19_street_NY', 'gender': 'female'},
{'name': 'smith', 'age': '14', 'hometown': '7_street_NY', 'gender': 'male'}]
I am new in python and tried to understand the working with dictionaries operations but stuck in between.
I have data like below:
[{'mesure':'10', 'name': 'mumbai', 'age': '15', 'class':'kg1'}, {'mesure':'20', 'name': 'hyd', 'age': '20', 'class':'kg2'},{'mesure':'11', 'name': 'mumbai', 'age': '145', 'class':'kg6'}, {'mesure':'21', 'name': 'hyd', 'age': '20', 'class':'kg2'}, {'mesure':'40', 'name': 'pune', 'age': '30', 'class':'kg4'}, {'mesure':'30', 'name': 'chennai', 'age': '25', 'class':'kg3'}, {'mesure':'41', 'name': 'pune', 'age': '30', 'class':'kg7'}, {'mesure':'22', 'name': 'hyd', 'age': '20', 'class':'kg2'}{'mesure':'12', 'name': 'mumbai', 'age': '40', 'class':'kg7'}, {'mesure':'46', 'name': 'pune', 'age': '30', 'class':'kg8'}]
I want to convert it in format like:
[{"Name": "mumbai",
"data": [{'mesure':'10', 'name': 'mumbai', 'age': '15', 'class':'kg1'},
{'mesure':'11', 'name': 'mumbai', 'age': '145', 'class':'kg6'},
{'mesure':'12', 'name': 'mumbai', 'age': '40', 'class':'kg7'}]}
{"Name": "hyd",
"data":[{'mesure':'20', 'name': 'hyd', 'age': '20', 'class':'kg2'},
{'mesure':'21', 'name': 'hyd', 'age': '20', 'class':'kg2'},
{'mesure':'22', 'name': 'hyd', 'age': '20', 'class':'kg2'}]}
{"Name": "pune",
"data":[{'mesure':'40', 'name': 'pune', 'age': '30', 'class':'kg4'},
{'mesure':'41', 'name': 'pune', 'age': '30', 'class':'kg7'},
{'mesure':'46', 'name': 'pune', 'age': '30', 'class':'kg8'}]}]
I Tried:
def dir_data(data):
main_list = []
main_dir = []
for i in data:
names = i["name"]
main_dir.append({"name": names, "data": i})
print(main_dir)
if __name__== "__main__":
data = [{'mesure':'10', 'name': 'mumbai', 'age': '15', 'class':'kg1'}, {'mesure':'20', 'name': 'hyd', 'age': '20', 'class':'kg2'},{'mesure':'11', 'name': 'mumbai', 'age': '145', 'class':'kg6'}, {'mesure':'21', 'name': 'hyd', 'age': '20', 'class':'kg2'}, {'mesure':'40', 'name': 'pune', 'age': '30', 'class':'kg4'}, {'mesure':'30', 'name': 'chennai', 'age': '25', 'class':'kg3'}, {'mesure':'41', 'name': 'pune', 'age': '30', 'class':'kg7'}, {'mesure':'22', 'name': 'hyd', 'age': '20', 'class':'kg2'}{'mesure':'12', 'name': 'mumbai', 'age': '40', 'class':'kg7'}, {'mesure':'46', 'name': 'pune', 'age': '30', 'class':'kg8'}]
dir_data(data)
I tried above code but couldn't get exact output so please guide me to get it....
Thank you
def dir_data(data):
items = []
names = []
for i in data:
if i['name'] not in names:
items.append({"Name": i['name'], "data": [i]})
names.append(i['name'])
else:
iname = names.index(i['name'])
items[iname]['data'].append(i)
return items
data = [{'mesure':'10', 'name': 'mumbai', 'age': '15', 'class':'kg1'},
{'mesure':'20', 'name': 'hyd', 'age': '20', 'class':'kg2'},
{'mesure':'11', 'name': 'mumbai', 'age': '145', 'class':'kg6'},
{'mesure':'21', 'name': 'hyd', 'age': '20', 'class':'kg2'},
{'mesure':'40', 'name': 'pune', 'age': '30', 'class':'kg4'},
{'mesure':'30', 'name': 'chennai', 'age': '25', 'class':'kg3'},
{'mesure':'41', 'name': 'pune', 'age': '30', 'class':'kg7'},
{'mesure':'22', 'name': 'hyd', 'age': '20', 'class':'kg2'},
{'mesure':'12', 'name': 'mumbai', 'age': '40', 'class':'kg7'},
{'mesure':'46', 'name': 'pune', 'age': '30', 'class':'kg8'}
]
print(dir_data(data))
Try that one.
I can see the code you have written seems to be working but, you haven't returning the function, comma missing in data and also there is some mistakes in the way of call the function.
Just call the function like this,
def dir_data(data):
main_list = []
main_dir = []
for i in data:
names = i["name"]
main_dir.append({"name": names, "data": i})
return(main_dir)
data = [{'mesure':'10', 'name': 'mumbai', 'age': '15', 'class':'kg1'}, {'mesure':'20', 'name': 'hyd', 'age': '20', 'class':'kg2'},{'mesure':'11', 'name': 'mumbai', 'age': '145', 'class':'kg6'}, {'mesure':'21', 'name': 'hyd', 'age': '20', 'class':'kg2'}, {'mesure':'40', 'name': 'pune', 'age': '30', 'class':'kg4'}, {'mesure':'30', 'name': 'chennai', 'age': '25', 'class':'kg3'}, {'mesure':'41', 'name': 'pune', 'age': '30', 'class':'kg7'}, {'mesure':'22', 'name': 'hyd', 'age': '20', 'class':'kg2'},{'mesure':'12', 'name': 'mumbai', 'age': '40', 'class':'kg7'}, {'mesure':'46', 'name': 'pune', 'age': '30', 'class':'kg8'}]
dir_data(data)
You can get desired solution by using below code
test_data = [{'mesure': '10', 'name': 'mumbai', 'age': '15', 'class': 'kg1'}, {'mesure': '20', 'name': 'hyd', 'age': '20', 'class': 'kg2'}, {'mesure': '11', 'name': 'mumbai', 'age': '145', 'class': 'kg6'}, {'mesure': '21', 'name': 'hyd', 'age': '20', 'class': 'kg2'}, {'mesure': '40', 'name': 'pune', 'age': '30', 'class': 'kg4'}, {'mesure': '30', 'name': 'chennai', 'age': '25', 'class': 'kg3'}, {'mesure': '41', 'name': 'pune', 'age': '30', 'class': 'kg7'}, {'mesure': '22', 'name': 'hyd', 'age': '20', 'class': 'kg2'}, {'mesure': '12', 'name': 'mumbai', 'age': '40', 'class': 'kg7'}, {'mesure': '46', 'name': 'pune', 'age': '30', 'class': 'kg8'}]
dic = dict()
for i in test_data:
dic.setdefault(i['name'].title(),[]).append(i)
result = [{"name":k ,"data":v} for k,v in dic.items()]
Output
[{'data': [{'class': 'kg4', 'age': '30', 'name': 'pune', 'mesure': '40'},
{'class': 'kg7', 'age': '30', 'name': 'pune', 'mesure': '41'},
{'class': 'kg8', 'age': '30', 'name': 'pune', 'mesure': '46'}], 'name': 'Pune'},
{'data': [{'class': 'kg3', 'age': '25', 'name': 'chennai', 'mesure': '30'}], 'name': 'Chennai'},
{ 'data': [{'class': 'kg2', 'age': '20', 'name': 'hyd', 'mesure': '20'},
{'class': 'kg2', 'age': '20', 'name': 'hyd', 'mesure': '21'},
{'class': 'kg2', 'age': '20', 'name': 'hyd', 'mesure': '22'}], 'name': 'Hyd'},
{
'data': [{'class': 'kg1', 'age': '15', 'name': 'mumbai', 'mesure': '10'},
{'class': 'kg6', 'age': '145', 'name': 'mumbai', 'mesure': '11'},
{'class': 'kg7', 'age': '40', 'name': 'mumbai', 'mesure': '12'}], 'name': 'Mumbai'}]
Try this:
import json
data = [{'mesure':'10', 'name': 'mumbai', 'age': '15', 'class':'kg1'}, {'mesure':'20', 'name': 'hyd', 'age': '20', 'class':'kg2'},{'mesure':'11', 'name': 'mumbai', 'age': '145', 'class':'kg6'}, {'mesure':'21', 'name': 'hyd', 'age': '20', 'class':'kg2'}, {'mesure':'40', 'name': 'pune', 'age': '30', 'class':'kg4'}, {'mesure':'30', 'name': 'chennai', 'age': '25', 'class':'kg3'}, {'mesure':'41', 'name': 'pune', 'age': '30', 'class':'kg7'}, {'mesure':'22', 'name': 'hyd', 'age': '20', 'class':'kg2'},{'mesure':'12', 'name': 'mumbai', 'age': '40', 'class':'kg7'}, {'mesure':'46', 'name': 'pune', 'age': '30', 'class':'kg8'}]
def dir_data(data):
# set guarantees the uniqueness of each name
names = set([item['name'] for item in data])
main_dir = []
# collect the data for each name
for name in names:
name_data = [d for d in data if d['name']==name]
main_dir.append({"Name":name,"data":name_data})
return json.dumps(main_dir)
Below is the solution which will give you the exact result as described by you:
def checkKey(dict, key):
if key in dict:
return True
else:
return False
def dir_data(data):
for item in test:
if checkKey(tem_dict, item['name']):
tem_dict[item['name']].append(item)
else:
tem_dict[item['name']] = []
tem_dict[item['name']].append(item)
res_dict = {}
res = []
for item in tem_dict:
print item
res_dict['Name'] = item
res_dict['data'] = tem_dict[item]
res.append(res_dict)
res_dict = {}
return res
let me know if this works for you or not.
I'd like to store the following data in a data dictionary so that I can easily export it to a CSV file. The problem is that the columns for each school id are not always in the same order:
text = """
school id= 28392
name|year|degree|age|race
Susan A. Smith|2007|PhD|27|white
Fred Collins|2006|PhD|26|hispanic
Amber Real|2007|MBA|28|white
Mike Lee|2003|PhD|27|white
school id= 273533123
name|year|age|race|degree
John B. Black|2003|27|hispanic|MBA
Steven Smith|2005|28|black|PhD
Jacob Waters|2003|25|hispanic|MBA
school id = 3452332
name|year|race|age|degree
Peter Hintze|2002|white|27|Bachelors
Ann Graden|2004|black|25|MBA
Bryan Stewart|2004|white|28|PhD
"""
I'd like to be able to eventually output all data to a CSV file with the following headings:
school id|year|name|age|race|degree
Can I do this in Python?
This actually seems pretty easy. Process the file into a data structure, then export it into a csv.
school = None
headers = None
data = {}
for line in text.splitlines():
if line.startswith("school id"):
school = line.split('=')[1].strip()
headers = None
continue
if school is not None and headers is None:
headers = line.split('|')
continue
if school is not None and headers is not None and line:
if not school in data:
data[school] = []
datum = dict(zip(headers, line.split('|')))
data[school].append(datum)
In [29]: data
Out[29]:
{'273533123': [{'age': '27',
'degree': 'MBA',
'name': 'John B. Black',
'race': 'hispanic',
'year': '2003'},
{'age': '28',
'degree': 'PhD',
'name': 'Steven Smith',
'race': 'black',
'year': '2005'},
{'age': '25',
'degree': 'MBA',
'name': 'Jacob Waters',
'race': 'hispanic',
'year': '2003'}],
'28392': [{'age': '27',
'degree': 'PhD',
'name': 'Susan A. Smith',
'race': 'white',
'year': '2007'},
{'age': '26',
'degree': 'PhD',
'name': 'Fred Collins',
'race': 'hispanic',
'year': '2006'},
{'age': '28',
'degree': 'MBA',
'name': 'Amber Real',
'race': 'white',
'year': '2007'},
{'age': '27',
'degree': 'PhD',
'name': 'Mike Lee',
'race': 'white',
'year': '2003'}],
'3452332': [{'age': '27',
'degree': 'Bachelors',
'name': 'Peter Hintze',
'race': 'white',
'year': '2002'},
{'age': '25',
'degree': 'MBA',
'name': 'Ann Graden',
'race': 'black',
'year': '2004'},
{'age': '28',
'degree': 'PhD',
'name': 'Bryan Stewart',
'race': 'white',
'year': '2004'}]}