简体   繁体   English

在python中总结嵌套的dict

[英]Summing nested dict in python

I have a dict as following: What I need to do is to calculate total amount of each fruit.我有一个字典如下:我需要做的是计算每个水果的总量。

{
    "students": {
        "Mark":{
             "Mango":{
              "2017-01-01":1,
              "2018-01-01":1,
            },
             "Orange":{
              "2017-01-01":2,
              "2018-01-01":2,
            },
             "Banana":{
              "2017-01-01":3,
              "2018-01-01":3,
            }
        },
        "Tom":{
             "Mango":{
              "2017-01-01":5,
              "2018-01-01":5,
            },
             "Orange":{
              "2017-01-01":6,
              "2018-01-01":6,
            },
             "Banana":{
              "2017-01-01":7,
              "2018-01-01":7,
            }
        }
    }
}

My expectation is to get the following value我的期望是获得以下价值

Mango= total for 2017-01-01 = (6) ( Mark have 1 and Tom have 5)
Orange= total for 2017-01-01 (8) ( Mark  have 2 and Tom have 6)
Banana= total for 2017-01-01 (10) ( Mark have 3 and Tom have 7)

I was trying to achieve that through:我试图通过以下方式实现这一目标:

for name in students:
    for fruit in students[name]:
        for date in students[name][fruit ]:

But I was not able to calculate them但我无法计算它们

any I ideas?我有什么想法吗?

Your question is not really clear but based on what I could infer, here is a possible solution:你的问题不是很清楚,但根据我的推断,这是一个可能的解决方案:

from pprint import pprint
d = {
    'students': {
        'Mark': {
            'Mango': {
                '2017-01-01': 1,
                '2018-01-01': 1},
            'Orange': {
                '2017-01-01': 2,
                '2018-01-01': 2},
            'Banana': {
                '2017-01-01': 3,
                '2018-01-01': 3}
            },
        'Tom': {
            'Mango': {
                '2017-01-01': 5,
                '2018-01-01': 5},
            'Orange': {
                '2017-01-01': 6,
                '2018-01-01': 6},
            'Banana': {
                '2017-01-01': 7,
                '2018-01-01': 7}
            }
    }
}

fruits = {}
students = d['students']

for student in students:
    for fruit in students[student]:
        if fruit not in fruits:
            fruits[fruit] = {}
        for date in students[student][fruit]:
            if date not in fruits[fruit]:
                fruits[fruit][date] = students[student][fruit][date]
            else:
                fruits[fruit][date] += students[student][fruit][date]

pprint(fruits)

That will output this:这将输出:

{'Banana': {'2017-01-01': 10, '2018-01-01': 10},
 'Mango': {'2017-01-01': 6, '2018-01-01': 6},
 'Orange': {'2017-01-01': 8, '2018-01-01': 8}}

Lengthy problem but assuming I read your problem right I think this solution will work.冗长的问题,但假设我正确阅读了您的问题,我认为此解决方案会奏效。

Input:输入:

d = {
    "students": {
        "Mark":{
             "Mango":{
              "2017-01-01":1,
              "2018-01-01":1,
            },
             "Orange":{
              "2017-01-01":2,
              "2018-01-01":2,
            },
             "Banana":{
              "2017-01-01":3,
              "2018-01-01":3,
            }
        },
        "Tom":{
             "Mango":{
              "2017-01-01":5,
              "2018-01-01":5,
            },
             "Orange":{
              "2017-01-01":6,
              "2018-01-01":6,
            },
             "Banana":{
              "2017-01-01":7,
              "2018-01-01":7,
            }
        }
    }
}

Solution:解决方案:

from collections import namedtuple

d = .... #input nested dict

# Light weight object to make our lives easier
Entry = namedtuple('Entry', 'name product date quantity')
entries = [] # A list of each entry (a name product date and quantity)
# Lets turn our nested dict into a list of objects
for name, products in d["students"].items():
    for product, purchases in products.items():
        for date, quantity in purchases.items():
            entries.append(Entry(name, product, date, quantity))

def sort_by(x):
    # Sort by product name as str, date as str, then name as str
    return (x.product, x.date, x.name)

# Now we handle all the logic to get the output you wanted
if entries:
    entries.sort(key=sort_by) # Sort our list using our sort_by function
    cur_product, cur_date = entries[0].product, entries[0].date
    sum_for_prod_for_date, who_had_it = 0, ""
    for e in entries:
        # If our product or date doesnt match what we were working with
        if e.product != cur_product or e.date != cur_date:
            # Print out this result
            print("{0}= total for {1} = ({2}) ({3})".format(cur_product, cur_date, sum_for_prod_for_date, who_had_it[:-5]))# sum_for_prod_for_date
            sum_for_prod_for_date, who_had_it = 0, ""
            cur_product, cur_date = e.product, e.date
        who_had_it += "{} have {} and ".format(e.name, e.quantity)
        sum_for_prod_for_date += e.quantity

Output:输出:

Banana= total for 2017-01-01 = (10) (Mark have 3 and Tom have 7)
Banana= total for 2018-01-01 = (10) (Mark have 3 and Tom have 7)
Mango= total for 2017-01-01 = (6) (Mark have 1 and Tom have 5)
Mango= total for 2018-01-01 = (6) (Mark have 1 and Tom have 5)
Orange= total for 2017-01-01 = (8) (Mark have 2 and Tom have 6)

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

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