【问题标题】:Make a list of dictionaries based on existing dictionary根据现有词典制作词典列表
【发布时间】:2017-03-24 18:12:22
【问题描述】:

编写了一个脚本来获取每个用户在 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’}]

【问题讨论】:

  • final_instances 是一个列表是否有特殊原因?它可以是一个字典,其中键是用户名,值是要计数的类型字典吗?
  • 在混合重音符号和单引号以及缺少的大括号之间,此代码无法执行。请发布准确的代码。
  • 字典也可以作为 final_instances。我正在寻找user1n type1 的实例数,m type2 的实例数...等等

标签: python python-2.7 list dictionary


【解决方案1】:

您可以使用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)

【讨论】:

    【解决方案2】:

    另一种选择是使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},
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 2019-01-28
      • 1970-01-01
      • 2023-02-02
      • 2011-01-31
      相关资源
      最近更新 更多