1

更新以试图更清楚

我有三个字典列表,我想根据一个值将它们合并为一个。

列表看起来像这样。他们可以拥有多少个字典。

unplanned = [{'service__name': u'Email', 'service_sum': 4}, {'service__name': u'Peoplesoft', 'service_sum': 2}]
planned = [{'service__name': u'Email', 'service_sum': 2}, {'service__name': u'Gopher', 'service_sum': 2}, {'service__name': u'Peoplesoft', 'service_sum': 4}]
emerg = [{'service__name': u'Internet', 'service_sum': 1}]

我想获取 3 个列表并创建一个新列表,其中包含所有 3 个列表中的名称和按设定顺序排列的值或 0。所以我在想这样的事情。

[(Email, (4, 2, 0)), (Peoplesoft, (2, 4, 0)), Gopher, (0, 2, 0)), Internet, (0, 0, 1))]

我想我应该创建一个 service__name 的列表来与每个列表进行比较,所以我这样做了,但我不确定如何将 3 个列表与这个列表进行比较。我认为 izip_longest 会起作用,但不知道如何实现它。我正在使用 2.7。

4

3 回答 3

2

只需使用字典,然后将其转换为列表:

some_list = [{'service__name': u'Email', 'service_sum': 4}, {'service__name': u'Email', 'service_sum': 1}, {'service__name': u'Network', 'service_sum': 0}]

def combine(list):
   combined = {}
   for item in list:
      if item['service__name'] not in combined:
         combined[item['service__name']] = []
      combined[item['service__name']].append(item['service_sum'])
   return combined.items()

combine(some_list)  # [(u'Email', [4, 1]), (u'Network', [0])]
combine(unplanned)
combine(emerg + planned)
.....

这是使用 defaultdict 的函数版本:

def combine(list):
   from collections import defaultdict
   combined = defaultdict(list)
   for item in list:
      combined[item['service__name']].append(item['service_sum'])
   return combined.items()

更简洁一些,但有一个不必要的导入,如果函数定义发生更改,将来可能会出现一些其他问题(请参阅注释)。

于 2012-09-13T17:58:18.687 回答
1

似乎您可以执行以下操作:

output = []
for dicts in zip(unplanned,planned,emerg):
    output.append(('Email',tuple(d['service_sum'] if d['service__name'] == 'Email' else 0 for d in dicts)))
于 2012-09-13T17:57:59.410 回答
0

试试下面的代码。你可以给变量更好的名字,因为你更了解上下文。

def convert(unplanned, planned, emerg):
    chain = (unplanned, planned, emerg)
    names = map(lambda lst: [d['service__name'] for d in lst], chain)
    sums = map(lambda lst: [d['service_sum'] for d in lst], chain)
    ds = [dict(zip(n, s)) for n,s in zip(names, sums)]
    unique_names = set([])
    unique_names = reduce(unique_names.union,names)
    results = []
    for n in unique_names:
        s = []
        for i in range(3):
            s.append(ds[i].get(n,0))
        results.append((n, tuple(s)))

    return results

print convert(unplanned, planned, emerg)

我机器上的输出是

[(u'Internet', (0, 0, 1)), (u'Peoplesoft', (2, 4, 0)), (u'Email', (4, 2, 0)), (u'Gopher', (0, 2, 0))]
于 2012-09-14T06:39:48.407 回答