嵌套字典理解

时间:2017-06-23 21:21:37

标签: python dictionary nested

对于以下嵌套字典,我想分别对每个'ab''bc''cd''de'键的值求和。基本上,折叠字典。最好是使用=sum理解,但无法弄清楚正确的语法:

{'hot': {'111': {'ab': 1, 'bc': 3, 'cd': 5, 'de': 7}}}
{'hot': {'111': {'ab': 12.5, 'bc': -31, 'cd': 2.5, 'de': 13}}}
{'hot': {'111': {'ab': 10, 'bc': 3, 'cd': 0, 'de': -2}}}

{'hot': {'110': {'ab': -1, 'bc': 0, 'cd': 1, 'de': 1}}}
{'hot': {'110': {'ab': 8, 'bc': 20, 'cd': 41, 'de': 13}}}
{'hot': {'110': {'ab': 1.75, 'bc': 2.3, 'cd': 6, 'de': 0}}}

{'hot': {'109': {'ab': 2.7, 'bc': 24, 'cd': 4, 'de': 5}}}
{'hot': {'109': {'ab': 41, 'bc': 6, 'cd': 12, 'de': 33}}}
{'hot': {'109': {'ab': 32, 'bc': 7, 'cd': 18, 'de': 3.75}}}

{'cold': {'111': {'ab': 25, 'bc': 2, 'cd': 3, 'de': 2.1}}}
{'cold': {'111': {'ab': 5, 'bc': 8, 'cd': 5, 'de': 17}}}
{'cold': {'111': {'ab': -71, 'bc': 42, 'cd': 5, 'de': 16}}}

{'cold': {'110': {'ab': 23, 'bc': 2.4, 'cd': 2.1, 'de': 4.3}}}
{'cold': {'110': {'ab': 11, 'bc': 2.8, 'cd': 4.5, 'de': 2.4}}}
{'cold': {'110': {'ab': 4, 'bc': 5.7, 'cd': 8.7, 'de': 1}}}        

期望的输出:

dict['hot']['111'][AB] = 1 + 12.5 + 10 = 23.5
dict['hot']['111'][BC] = 3 - 31 + 3 = - 25

2 个答案:

答案 0 :(得分:1)

我假设你的数据在一个列表中,因为有了这个,你得到了你期望的答案。

data = [{'hot': {'111': {'ab': 1, 'bc': 3, 'cd': 5, 'de': 7}}},
{'hot': {'111': {'ab': 12.5, 'bc': -31, 'cd': 2.5, 'de': 13}}},
{'hot': {'111': {'ab': 10, 'bc': 3, 'cd': 0, 'de': -2}}},

{'hot': {'110': {'ab': -1, 'bc': 0, 'cd': 1, 'de': 1}}},
{'hot': {'110': {'ab': 8, 'bc': 20, 'cd': 41, 'de': 13}}},
{'hot': {'110': {'ab': 1.75, 'bc': 2.3, 'cd': 6, 'de': 0}}},

{'hot': {'109': {'ab': 2.7, 'bc': 24, 'cd': 4, 'de': 5}}},
{'hot': {'109': {'ab': 41, 'bc': 6, 'cd': 12, 'de': 33}}},
{'hot': {'109': {'ab': 32, 'bc': 7, 'cd': 18, 'de': 3.75}}},

{'cold': {'111': {'ab': 25, 'bc': 2, 'cd': 3, 'de': 2.1}}},
{'cold': {'111': {'ab': 5, 'bc': 8, 'cd': 5, 'de': 17}}},
{'cold': {'111': {'ab': -71, 'bc': 42, 'cd': 5, 'de': 16}}},

{'cold': {'110': {'ab': 23, 'bc': 2.4, 'cd': 2.1, 'de': 4.3}}},
{'cold': {'110': {'ab': 11, 'bc': 2.8, 'cd': 4.5, 'de': 2.4}}},
{'cold': {'110': {'ab': 4, 'bc': 5.7, 'cd': 8.7, 'de': 1}}}  ]

代码是这样的:

from collections import defaultdict
counts = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))

for d in data:                   # for the list
    for k1 in d:                 # for the hot-cold level
        for k2 in d[k1]:         # for the 1[0-9]{2} level
            for k3 in d[k1][k2]: # for the [a-z]{2} level
                counts[k1][k2][k3] += d[k1][k2][k3]

print(counts['hot']['111']['ab'])
print(counts['hot']['111']['bc'])

有两个级别的defaultdict嵌套。

输出:

23.5
-25

答案 1 :(得分:0)

此示例正在制作“getter”功能。与一次解析整个dict列表相比,可能减少一点开销。

这里的双字典迭代可以通过简单地在第一次迭代中解析接受的字典来减少,但是为了演示目的,它被分成accepted和第二个迭代器。

这是一个完整的代码示例,用于打印出所需的结果23.5。 首先,创建一个您想要阅读的词典列表:

dictionaries = [
    {'hot': {'111': {'ab': 1, 'bc': 3, 'cd': 5, 'de': 7}}},
    {'hot': {'111': {'ab': 12.5, 'bc': -31, 'cd': 2.5, 'de': 13}}},
    {'hot': {'111': {'ab': 10, 'bc': 3, 'cd': 0, 'de': -2}}},

    {'hot': {'110': {'ab': -1, 'bc': 0, 'cd': 1, 'de': 1}}},
    {'hot': {'110': {'ab': 8, 'bc': 20, 'cd': 41, 'de': 13}}},
    {'hot': {'110': {'ab': 1.75, 'bc': 2.3, 'cd': 6, 'de': 0}}},

    {'hot': {'109': {'ab': 2.7, 'bc': 24, 'cd': 4, 'de': 5}}},
    {'hot': {'109': {'ab': 41, 'bc': 6, 'cd': 12, 'de': 33}}},
    {'hot': {'109': {'ab': 32, 'bc': 7, 'cd': 18, 'de': 3.75}}},

    {'cold': {'111': {'ab': 25, 'bc': 2, 'cd': 3, 'de': 2.1}}},
    {'cold': {'111': {'ab': 5, 'bc': 8, 'cd': 5, 'de': 17}}},
    {'cold': {'111': {'ab': -71, 'bc': 42, 'cd': 5, 'de': 16}}},

    {'cold': {'110': {'ab': 23, 'bc': 2.4, 'cd': 2.1, 'de': 4.3}}},
    {'cold': {'110': {'ab': 11, 'bc': 2.8, 'cd': 4.5, 'de': 2.4}}},
    {'cold': {'110': {'ab': 4, 'bc': 5.7, 'cd': 8.7, 'de': 1}}}
]

接下来,制作你的功能。

def get_sum(temp, num, pt):
    accepted = [] # Initialize a list of accepted dictionaries that fit the arguments passed.
    pt_sum = 0 # Initialize the variable for the sum of your parts, starting at 0.

    for dictionary in dictionaries: # Iterate through the dictionary list.
        if temp in dictionary and num in dictionary[temp]: # Check if the dict on current iteration has what you want.
            accepted.append(dictionary[temp][num]) # It does, so add it to accepted.
            # Let's pause here. Say you are reading the first dict in the list. So that means, this is what the fuction is working with:
            # {'hot': {'111': {'ab': 1, 'bc': 3, 'cd': 5, 'de': 7}}}
            # Now with the append function, we are calling "dictionary[temp][num]".
            # We know that each of these keys exist, because we just checked it.
            # So this eliminates the need to add the whole dictionary to "accepted".
            # Basically, we are cutting out the last section, because that's what we need. So you end up with:
            # "{'ab': 1, 'bc': 3, 'cd': 5, 'de': 7}" in the list "accepted".

    for dictionary in accepted: # Now go through the ones that have the data you need.
        pt_sum += dictionary[pt] # And simply add the value to the sum.

    return pt_sum # Return the part sum.

现在你可以使用它了:

print(get_sum("hot", "111", "ab"))

>>> 23.5

我在顶部提到的简化代码是:

def get_sum(temp, num, pt):
    pt_sum = 0

    for dictionary in dictionaries:
        if temp in dictionary and num in dictionary[temp]:
            pt_sum += dictionary[temp][num][pt]

    return pt_sum

基本上只是在第一个循环中添加pt_sum,所以没有第二次迭代,这是永远不需要的。