根据现有字典制作字典列表

时间:2017-03-24 18:12:22

标签: python python-2.7 list dictionary

编写脚本以获取AWS上每个用户运行的实例列表。我有一个词典列表。我想排序并列出每个用户运行的实例数(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'}]

创建了一个包含用户名和实例类型的两个列表。

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

尝试:

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)

我没有得到预期的输出,如下所示。我的逻辑无法获得预期的结果。有人可以帮我这个。提前谢谢!

目标: 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 个答案:

答案 0 :(得分:4)

您可以使用collections.Counter在用户分组原始的词典列表后进行计数:

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)

答案 1 :(得分: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

(请注意,这使用隐含Python内置的变量名type。我使用它是因为这是你的字段的名称,但在我自己的代码中我将字段名称更改为从不影响内置。)

最后,您得到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},
}