简体   繁体   English

使用公共键/值在Python字典列表中求值

[英]Sum values in a Python list of dictionaries using a common key/value

Apologies if this question has already been asked. 如果已经提出这个问题,请道歉。 I'm a newbie at this but I've looked at a couple of other questions/answers that appear similar to mine but can't find one that does the trick. 我是一个新手,但我看了几个其他问题/答案,看起来与我的相似,但找不到一个可以解决问题的问题。 I've tried Counter but can't seem to figure out how to keep the ID key/value. 我已经尝试过Counter,但似乎无法弄清楚如何保持ID键/值。

I'm trying to sum the values in a Python dictionary using a common key/value. 我正在尝试使用公共键/值来汇总Python字典中的值。 Eg, 例如,

list = [
    {'ID':1, 'T2':10, 'T3':20},
    {'ID':2, 'T2':5, 'T3':0},
    {'ID':1, 'T2':5, 'T3':10},
    {'ID':2, 'T2':10, 'T3':30},
    {'ID':3, 'T2':5, 'T3':0}
]

but I need this: 但我需要这个:

newlist = [
    {'ID':1, 'T2':15, 'T3':30}, 
    {'ID':2, 'T2':15, 'T3':30}, 
    {'ID':3, 'T2':5, 'T3':0}
]

Any help appreciated. 任何帮助赞赏。

UPDATE: 更新:

I have borrowed from another answer and tried this: 我借用了另一个答案并尝试了这个:

superdict = {}
for d in rows:
  for k, v in d.items():
      if superdict.get(k) is None:
          superdict[k] = []
      if superdict.get(k) is not None:
          superdict[k].append(v)    

But instead of keeping getting a new list of combined/added values, I get something like this: 但是,我没有得到一个新的组合/添加值列表,而是得到这样的结果:

'ID': ['3903', '3997', '3997', '3997', '3947', '4097', '3445', 
       '3997', '4107', '3997', '3445', '3997', '3997', '3997', 
       '3997', '3445', '3997', etc. etc.

UPDATE 2: 更新2:

Sorry for the confusion in regard to my examples. 很抱歉对我的例子感到困惑。 What I'm looking for is a way to keep the ID value static but add the other values in the dictionary. 我正在寻找的是一种保持ID值静态但在字典中添加其他值的方法。 So all of the values in corresponding to IDs with a value of 1 would be added together. 因此,对应于具有值1的ID的所有值将被加在一起。

Eg this: 例如:

list = [{'ID':1, 'T2':10, 'T3':20}, {'ID':1, 'T2':5, 'T3':10}]

Becomes this: 变成这样:

newlist = [{'ID':1, 'T2':15, 'T3':30}]

Hope this helps. 希望这可以帮助。

It's hard to understand what your desired result is supposed to be with your given inputs. 很难理解您的预期结果应该与您的输入结果一致。 Give a concrete example of the expected/correct output. 给出预期/正确输出的具体示例。

I suspect this is what you are going for? 我怀疑这就是你想要的?

my_list = [{'ID':1, 'T2':10, 'T3':20},
           {'ID':2, 'T2':5, 'T3':0}, 
           {'ID':1, 'T2':5, 'T3':10}, 
           {'ID':2, 'T2':10, 'T3':30}, 
           {'ID':3, 'T2':5, 'T3':0}]

new_dictionary = {}
for dictionary in my_list:
    for key, value in dictionary.items():
        if new_dictionary.has_key(key):
            new_dictionary[key] = value + new_dictionary[key]
        else:
            new_dictionary[key] = value

#Output:
>>>new_dictionary
{'T2': 35, 'ID': 9, 'T3': 60}

If I understood your needs correctly, here is a solution: 如果我正确理解您的需求,这是一个解决方案:

def sum_by_common_key(input_list, index_key='ID'):
    output_dict = {}
    for d in input_list:
        index = d[index_key]
        if index not in output_dict:
            output_dict[index] = {}
        for k, v in d.items():
            if k not in output_dict[index]:
                output_dict[index][k] = v
            elif k != index_key:
                output_dict[index][k] += v
    return output_dict.values()

l = [{'ID':1, 'T2':10, 'T3':20}, {'ID':2, 'T2':5, 'T3':0}, {'ID':1, 'T2':5, 'T3':10}, {'ID':2, 'T2':10, 'T3':30}, {'ID':3, 'T2':5, 'T3':0}]
print sum_by_common_key(l)

>>> [{'T2': 15, 'ID': 1, 'T3': 30}, {'T2': 15, 'ID': 2, 'T3': 30}, {'T2': 5, 'ID': 3, 'T3': 0}]

I hope this will help you: 我希望这能帮到您:

>>> from collections import Counter
>>> old_list=[{'ID':1, 'T2':10, 'T3':20}, {'ID':2, 'T2':5, 'T3':0}, {'ID':1, 'T2':5, 'T3':10}, {'ID':2, 'T2':10, 'T3':30}, {'ID':3, 'T2':5, 'T':0}]
>>> new_list=[]
>>> for i,a in enumerate(old_list):
...     z=0
...     for b in old_list[i+1:]:
...        if a['ID']==b['ID']:
...           new_list.append(dict(Counter(a)+Counter(b)))
...           new_list[-1]['ID']=a['ID']
...           temp=old_list.pop(old_list.index(b))
...           z=1
...     if not z:
...        new_list.append(a)
... 
>>> new_list
[{'T2': 15, 'ID': 1, 'T3': 30}, {'T2': 15, 'ID': 2, 'T3': 30}, {'T2': 5, 'ID': 3, 'T3': 0}]

If interpret this properly, the goal is to group by the value for key 'ID' then to sum the values of the corresponding keys within the group. 如果正确解释这一点,目标是按键'ID'的值进行分组,然后对组内相应键的值求和。 If the keys are consistent ie all keys from the first dict are guaranteed to show in the later dicts, here is aa solution: 如果密钥是一致的,即第一个字典中的所有密钥都保证在后面的代码中显示,这里有一个解决方案:

my_list = [{'ID':1, 'T2':10, 'T3':20},
           {'ID':2, 'T2':5, 'T3':0}, 
           {'ID':1, 'T2':5, 'T3':10}, 
           {'ID':2, 'T2':10, 'T3':30}, 
           {'ID':3, 'T2':5, 'T3':0}]


# prep keys
id_keys = set([ z['ID'] for z in my_list ])
sum_keys = [ z for z in my_list[0].keys() if z != 'ID' ]
print('ids to group by', id_keys)
print('keys to sum over', sum_keys)

# restructure the data
big = [ [z.pop('ID'), z] for z in my_list ]
print('[[group_key, {remaining dict],] :\n', big)

# initiate results accumulator
rez = {idd: dict.fromkeys(sum_keys, 0) for idd in id_keys }
print('empty accumulator', rez)

# two loops in list comprehension
[ rez[g[0]].update({k: rez[g[0]][k] + g[1][k]}) for k in sum_keys for g in big ]
print('result', rez)

Output: 输出:

ids to group by {1, 2, 3}
keys to sum over ['T2', 'T3']
[[group_key, {remaining dict],] :
 [[1, {'T2': 10, 'T3': 20}], [2, {'T2': 5, 'T3': 0}], [1, {'T2': 5, 'T3': 10}], [2, {'T2': 10, 'T3': 30}], [3, {'T2': 5, 'T3': 0}]]
empty accumulator {1: {'T2': 0, 'T3': 0}, 2: {'T2': 0, 'T3': 0}, 3: {'T2': 0, 'T3': 0}}
result {1: {'T2': 15, 'T3': 30}, 2: {'T2': 15, 'T3': 30}, 3: {'T2': 5, 'T3': 0}}
[Finished in 0.2s]

If the goal is to sum over keys, and the keys are not guaranteed to match from one dict to the next, use the following code: 如果目标是对密钥求和,并且不保证密钥从一个字典匹配到下一个字典,请使用以下代码:

my_list = [{'T1':1, 'T2':10, 'T3':20},
           {'T1':2, 'T2':5 , 'T3':0}, 
           {        'T2':5 ,       }, 
           {        'T2':10, 'T3':30, 'T4': 7}, 
           {'T1':3, 'T2':5 , 'T3':0 , 'T4': 3}]

rez = {}
for dic in my_list:
    for key in dic.keys():
        rez[key]=rez.setdefault(key, 0) + dic[key]

print(rez)

Output: 输出:

{'T1': 6, 'T2': 35, 'T3': 50, 'T4': 10}

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

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