Make a list of dictionaries based on existing dictionary

Refresh

November 2018

Views

48 time

1

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’}]

2 answers

1

Другим вариантом является создание final_instancesсловаря вместо списка, а затем каждый подсчитывать в intвместо 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

(Обратите внимание , что это использует имя переменного , typeкоторая тень на Python встроенной команды. Я использовал его , потому что это имя вашего поля, но в моем собственном коде я изменить имена полей никогда не теневые встроенные команд.)

В конце этого, вы получаете final_instancesкак:

{
    'user1': {'m4.large': 2, 't2.medium': 1, 't2.small': 3},
    'user2': {'m4.large': 1, 't2.medium': 2},
    'user3': {'m4.large': 1, 't2.small': 1},
}
4

Вы можете использовать , collections.Counterчтобы взять отсчеты после группирования исходного списка dicts пользователя:

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'}]

Если вы хотите , чтобы отсчеты в конечном итоге как строки, вы можете использовать словарь понимание бросить значения счетчика перед добавлением в список.

...
d = {k: str(v) for k, v in c.items()}
lst.append(d)