python中嵌套dict的求和

python中嵌套dict的求和,python,python-3.x,Python,Python 3.x,我的口述如下: 我需要做的是计算每种水果的总量 { "students": { "Mark":{ "Mango":{ "2017-01-01":1, "2018-01-01":1, }, "Orange":{ "2017-01-01":2, "2018-01-01":2,

我的口述如下: 我需要做的是计算每种水果的总量

{
    "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,
            }
        }
    }
}
我的期望是得到以下值

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)
我试图通过以下方式实现这一目标:

for name in students:
    for fruit in students[name]:
        for date in students[name][fruit ]:
但我无法计算它们


我有什么想法吗

你的问题并不十分清楚,但根据我的推断,这里有一个可能的解决方案:

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)
这将输出以下内容:

{'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}}

冗长的问题,但假设我正确理解了你的问题,我认为这个解决方案会奏效

输入:

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,
            }
        }
    }
}
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
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)
解决方案:

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,
            }
        }
    }
}
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
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)
输出:

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

我有一个json文件,只是试图展示文件格式的样子。而且,我不知道为什么预期的输出是2个芒果、8个橙色和10个香蕉。你是如何得到这些数字的?OP想把每天水果的数量加起来。@accdias但是为什么是2芒果而不是6?你需要显示一个完整的代码片段。“我无法计算它们”并不能解释你的处境。