简体   繁体   中英

Python dictionary: Add to the key sum of values fulfilling given condition

I've following nested dictionary, where the first number is resource ID (the total number of IDs is greater than 100 000):

dict = {1: {'age':1,'cost':14,'score':0.3},
        2: {'age':1,'cost':9,'score':0.5},
        ...}

I want to add to each resource a sum of costs of resources with lower score than given resource. I can add 'sum_cost' key which is equal to 0 by following code:

for id in adic:
    dict[id]['sum_cost'] = 0

It gives me following:

dict = {1: {'age':1,'cost':14,'score':0.3, 'sum_cost':0},
        2: {'age':1,'cost':9,'score':0.5,'sum_cost':0},
        ...}

Now I would like to use ideally for loop (to make the code easily readable) to assign to each sum_cost a value equal of sum of cost of IDs with lower score than the given ID.

Ideal output looks like dictionary where 'sum_cost' of each ID is equal to the cost of IDs with lower score than given ID:

dict = {1: {'age':1,'cost':14,'score':0.3, 'sum_cost':0},
        2: {'age':1,'cost':9,'score':0.5,'sum_cost':21},
        3: {'age':13,'cost':7,'score':0.4,'sum_cost':14}}

Is there any way how to do it?

Notes:

Using sorted method for sorting the dictionary output corresponding to the key score

dictionary get method to get dictionary values

and using a temporary variable for cumulative addition os sum_cost

Code:

dicts = {1: {'age': 1, 'cost': 14, 'score': 0.3, 'sum_cost': 0},
         2: {'age': 1, 'cost': 9, 'score': 0.5, 'sum_cost': 0},
         3: {'age': 13, 'cost': 7, 'score': 0.4, 'sum_cost': 0}}

sum_addition = 0

for key, values in sorted(dicts.items(), key=lambda x: x[1].get('score', None)):
    if dicts[key].get('score') is not None: #By default gives None when key is not available
        dicts[key]['sum_cost'] = sum_addition
        sum_addition += dicts[key]['cost']
        print key, dicts[key]

A even more simplified method by @BernarditoLuis and @Kevin Guan advise

Code2:

dicts = {1: {'age': 1, 'cost': 14, 'score': 0.3, 'sum_cost': 0},
         2: {'age': 1, 'cost': 9, 'score': 0.5, 'sum_cost': 0},
         3: {'age': 13, 'cost': 7, 'score': 0.4, 'sum_cost': 0}}

sum_addition = 0

for key, values in sorted(dicts.items(), key=lambda x: x[1].get('score', None)):
    if dicts[key].get('score'): #By default gives None when key is not available
        dicts[key]['sum_cost'] = sum_addition
        sum_addition += dicts[key]['cost']
        print key, dicts[key]

Output:

1 {'sum_cost': 0, 'age': 1, 'cost': 14, 'score': 0.3}
3 {'sum_cost': 14, 'age': 13, 'cost': 7, 'score': 0.4}
2 {'sum_cost': 21, 'age': 1, 'cost': 9, 'score': 0.5}

What about using OrderedDict?

from collections import OrderedDict

origin_dict = {
    1: {'age':1,'cost':14,'score':0.3}, 
    2: {'age':1,'cost':9,'score':0.5}, 
    3: {'age':1,'cost':8,'score':0.45}
}
# sort by score
sorted_dict = OrderedDict(sorted(origin_dict.items(), key=lambda x: x[1]['score']))
# now all you have to do is to count sum_cost successively starting from 0
sum_cost = 0
for key, value in sorted_dict.items():
    value['sum_cost'] = sum_cost
    sum_cost += value['cost']

print sorted_dict

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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