在Python中总结嵌套字典

时间:2019-04-12 13:48:05

标签: python python-3.x

我有一个字典,如下所示: 我需要做的是计算每种水果的总量。

{
    "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 ]:

但是我无法计算出它们

我有什么想法吗?

2 个答案:

答案 0 :(得分:0)

您的问题不是很清楚,但是根据我的推断,这是一个可能的解决方案:

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

答案 1 :(得分:0)

问题很严重,但假设我没看错,我认为此解决方案会起作用。

输入:

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)