简体   繁体   English

Python比较列表到Dict值

[英]Python Compare List to Dict Value

Updated in an attempt to be more clear 更新以试图更清楚

I have three list of dictionaries that I want to merge into one based on a value. 我有三个字典列表,我希望根据值合并为一个。

The lists looks like this. 列表看起来像这样。 They vary in how many dictionaries that they can have. 它们可以有多少字典。

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

I want to take the 3 lists and and create a new list that has the name's from all 3 lists and the values or 0 in a set order. 我想获取3个列表并创建一个新列表,其中包含来自所有3个列表的名称,以及设置顺序中的值或0。 So I am thinking something like this. 所以我在想这样的事情。

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

I thought I should create a list of the service__name's to compare against each list so I did that but I am not sure how to compare the 3 lists against this name list. 我以为我应该创建一个service__name的列表来比较每个列表,所以我这样做了,但我不知道如何将3个列表与这个名单进行比较。 I thought izip_longest would work but have no idea how to implement it. 我认为izip_longest可以工作,但不知道如何实现它。 I am using 2.7. 我使用的是2.7。

Just use a dict, then convert it into a list afterwards: 只需使用一个字典,然后将其转换为一个列表:

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)
.....

Here's the version of the function that uses defaultdict: 这是使用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()

A little cleaner, but there's an unnecessary import, and a few other problems with it that may pop up in the future if the function definition is changed (see comments). 有点干净,但有一个不必要的导入,以及一些其他问题,如果更改功能定义将来可能会弹出它(请参阅注释)。

It seems like you could do something like: 看起来你可以这样做:

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)))

Try the following codes. 请尝试以下代码。 You can give variables better name since you know better about the contexts. 您可以为变量提供更好的名称,因为您对上下文了解得更多。

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)

The output at my machine is 我机器的输出是

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM