Reputation: 705
Wrote a script to fetch list of instances run by each user on AWS. I got a list a dictionaries. I would like to sort and list the number of instances run by each user(list_instances
).
list_instances=[{'type': u't2.small', 'user': u'user1'},
{'type': u'm4.large', 'user': u'user1'},
{'type': u't2.medium', 'user': u'user1'},
{'type': u't2.small', 'user': u'user1'},
{'type': u'm4.large', 'user': u'user1'},
{'type': u't2.small', 'user': u'user1'},
{'type': u'm4.large', 'user': u'user2'},
{'type': u'm4.large', 'user': u'user3'},
{'type': u't2.medium', 'user': u'user2'},
{'type': u't2.medium', 'user': u'user2'},
{'type': u't2.small', 'user': u'user3'}]
created a two lists with user name and instance type.
names_list=[u'user1', u'user2', u'ben', u'user3', u'user4']
type_list=[u't2.small', u'm4.large', u'm4.large', u't2.medium', u't2.small', u'm4.large', u'm4.large', u't2.small']
Try:
val = 0
final_instances=[]
for ii in names_list:
temp_dic = {}
for jj in type_list:
for kk in list_instances:
if (ii == kk['user']) and (jj in kk):
#print ii,kk['user'],jj,kk,kk[jj]
temp_dic['user']=kk['user']
temp_dic[jj]=val+kk[jj]
final_a.append(temp_dic)
print (final_instances)
I didn't get the expected output as like below. My logic not efficient to get the expected result. Can someone help me on this. Thanks in advance!
Goal:
final_instances=
[{'user':u’user1’,’t2.small’:‘3’,’m4.large’:‘2’,’t2.medium’: ‘1’}
{'user': u’user2’,’m4.large’: ‘1’,’t2.medium’: ‘2’}
{'user': u’user3’,’t2.small’: ‘1’,’m4.large’: ‘1’}]
Upvotes: 1
Views: 62
Reputation: 78554
You can use collections.Counter
to take counts after grouping your original list of dicts by user:
from collections import Counter
from operator import itemgetter
from itertools import groupby
from pprint import pprint
f = itemgetter('user')
lst = []
for k, g in groupby(sorted(list_instances, key=f), f):
c = Counter({u'user': k})
c.update([d['type'] for d in g])
lst.append(dict(c))
pprint(lst)
[{u'm4.large': 2, u't2.medium': 1, u't2.small': 3, u'user': u'user1'},
{u'm4.large': 1, u't2.medium': 2, u'user': u'user2'},
{u'm4.large': 1, u't2.small': 1, u'user': u'user3'}]
If you want the counts to end up as strings, you can use a dictionary comprehension to cast values in the counter before appending to the list.
...
d = {k: str(v) for k, v in c.items()}
lst.append(d)
Upvotes: 4
Reputation: 2200
Another option is to make final_instances
a dictionary instead of a list, and then each count into int
instead of str
:
final_instances = {}
for instance in list_instances:
user = instance['user']
type = instance['type']
data = final_instances.get(user)
if data is None:
data = {}
final_instances[user] = data
count = data.get(type, 0)
data[type] = count + 1
(Note that this uses the variable name type
which shadows a Python builtin. I used it because that's the name of your field, but in my own code I change field names to never shadow builtins.)
At the end of this, you get final_instances
as:
{
'user1': {'m4.large': 2, 't2.medium': 1, 't2.small': 3},
'user2': {'m4.large': 1, 't2.medium': 2},
'user3': {'m4.large': 1, 't2.small': 1},
}
Upvotes: 1