Как вернуть новый словарь, если ключи в одном словаре совпадают с ключами в другом словаре?

В настоящее время у меня есть словарь, ключ которого представляет собой почтовый индекс, а значения также являются словарем.

d = { 94111: {'a': 5,  'b': 7,  'd': 7}, 
      95413: {'a': 6,  'd': 4}, 
      84131: {'a': 5,  'b': 15, 'c': 10, 'd': 11}, 
      73173: {'a': 15, 'c': 10, 'd': 15}, 
      80132: {'b': 7,  'c': 7,  'd': 7} }

И затем второй словарь, который связывает, к какому состоянию относится почтовый индекс.

states = {94111: "TX", 84131: "TX", 95413: "AL", 73173: "AL", 80132: "AL"}

Если почтовый индекс в states словаря совпадает с одним из ключей в db он суммирует эти значения и помещает его в новый словарь, как ожидаемый результат.

Ожидаемый результат:

{'TX': {'a': 10, 'b': 22, 'd': 18, 'c': 10}, 'AL': {'a': 21, 'd': 26, 'c': 17, 'b': 7}}

До сих пор я смотрю в этом направлении, но я не уверен, когда оба ключа совпадают, как создать словарь, который будет выглядеть как ожидаемый результат.

def zips(d, states):
    result = dict()
    for key, value in db.items():
        for keys, values in states.items():
            if key == keys:


zips(d, states)

Ответ 1

Использование модуля collections

Пример:

from collections import defaultdict, Counter

d = { 94111: {'a': 5,  'b': 7,  'd': 7}, 
      95413: {'a': 6,  'd': 4}, 
      84131: {'a': 5,  'b': 15, 'c': 10, 'd': 11}, 
      73173: {'a': 15, 'c': 10, 'd': 15}, 
      80132: {'b': 7,  'c': 7,  'd': 7} }

states = {94111: "TX", 84131: "TX", 95413: "AL", 73173: "AL", 80132: "AL"}

result = defaultdict(Counter)
for k,v in d.items():
    if k in states:
        result[states[k]] += Counter(v)
print(result)

Выход:

defaultdict(<class 'collections.Counter'>, {'AL': Counter({'d': 26, 'a': 21, 'c': 17, 'b': 7}), 
'TX': Counter({'b': 22, 'd': 18, 'a': 10, 'c': 10})})

Ответ 2

Вы можете просто использовать defaultdict и считать в цикле:

expected_output = defaultdict(lambda: defaultdict(int))
for postcode, state in states.items():
     for key, value in d.get(postcode, {}).items():
         expected_output[state][key] += value

Ответ 3

Следующее может работать

d = {
    94111: {'a': 5,  'b': 7,  'd': 7},
    95413: {'a': 6,  'd': 4},
    84131: {'a': 5,  'b': 15, 'c': 10, 'd': 11},
    73173: {'a': 15, 'c': 10, 'd': 15},
    80132: {'b': 7,  'c': 7,  'd': 7}
}
states = {
    94111: "TX",
    84131: "TX",
    95413: "AL",
    73173: "AL",
    80132: "AL"
}

print({v: d[k] for k, v in states.items() if k in d})

Ответ 4

Так же, как дополнение к ответу Ракеша, вот ответ ближе к вашему коду:

res = {v:{} for v in states.values()}

for k,v in states.items():
    if k in d:
        sub_dict = d[k]
        output_dict = res[v]
        for sub_k,sub_v in sub_dict.items():
            output_dict[sub_k] = output_dict.get(sub_k, 0) + sub_v

Ответ 5

Вы можете использовать что-то вроде этого:

d = { 94111: {'a': 5,  'b': 7,  'd': 7},                                                                                                                                                
      95413: {'a': 6,  'd': 4},                                                                 
      84131: {'a': 5,  'b': 15, 'c': 10, 'd': 11},                                              
      73173: {'a': 15, 'c': 10, 'd': 15},                                                       
      80132: {'b': 7,  'c': 7,  'd': 7} }                                                       
states = {94111: "TX", 84131: "TX", 95413: "AL", 73173: "AL", 80132: "AL"}                         

out = {i: 0 for i in states.values()}                                                              
for key, value in d.items():                                                                       
    if key in states:                                                                              
        if not out[states[key]]:                                                                   
            out[states[key]] = value                                                               
        else:                                                                                      
            for k, v in value.items():                                                             
                if k in out[states[key]]:                                                          
                    out[states[key]][k] += v                                                       
                else:                                                                              
                    out[states[key]][k] = v                                                        
# out -> {'TX': {'a': 10, 'b': 22, 'd': 18, 'c': 10}, 'AL': {'a': 21, 'd': 26, 'c': 17, 'b': 7}}

Ответ 6

Вы можете использовать класс Counter для подсчета объектов:

from collections import Counter

d = { 94111: {'a': 5,  'b': 7,  'd': 7}, 
      95413: {'a': 6,  'd': 4}, 
      84131: {'a': 5,  'b': 15, 'c': 10, 'd': 11}, 
      73173: {'a': 15, 'c': 10, 'd': 15}, 
      80132: {'b': 7,  'c': 7,  'd': 7} }

states = {94111: "TX", 84131: "TX", 95413: "AL", 73173: "AL", 80132: "AL"}

new_d = {}
for k, v in d.items():
    if k in states:
        new_d.setdefault(states[k], Counter()).update(v)

print(new_d)
# {'TX': Counter({'b': 22, 'd': 18, 'a': 10, 'c': 10}), 'AL': Counter({'d': 26, 'a': 21, 'c': 17, 'b': 7})}

Вы можете конвертировать new_d в словарь словарей:

for k, v in new_d.items():
    new_d[k] = dict(v)

print(new_d)
# {'TX': {'a': 10, 'b': 22, 'd': 18, 'c': 10}, 'AL': {'a': 21, 'd': 26, 'c': 17, 'b': 7}}

Ответ 7

Вы можете использовать метод dict .items(), который возвращает список кортежей и получает ожидаемый результат в простой однострочной строке:

new_dict = {value:d[key] for key, value in states.items()}

Выход:

{'AL': {'b': 7, 'c': 7, 'd': 7}, 'TX': {'a': 5, 'b': 15, 'c': 10, 'd': 11}}

Ответ 8

Это должно работать:

d = {
    94111: {'a': 5, 'b': 7, 'd': 7},
    95413: {'a': 6, 'd': 4},
    84131: {'a': 5, 'b': 15, 'c': 10, 'd': 11},
    73173: {'a': 15, 'c': 10, 'd': 15},
    80132: {'b': 7, 'c': 7, 'd': 7}
}

states = {
    94111: "TX",
    84131: "TX",
    95413: "AL",
    73173: "AL",
    80132: "AL"
}

return_dict = dict()

for state in states:
    if state in d:
        return_dict[states[state]] = d[state]

print(return_dict)

Ответ 9

Возможно, вы захотите пересмотреть свой выбор dict как хранить ваши данные. Если вы храните свои данные с помощью панд, агрегирование будет намного проще.

df = pd.DataFrame(d).transpose()
df['states']=pd.Series(states)
df.groupby('states').sum()

>>            a     b     c     d
>>states                        
>>AL      21.0   7.0  17.0  26.0
>>TX      10.0  22.0  10.0  18.0

Ответ 10

Это можно записать так:

d2 = {states[i]: d[i] for i in d.keys() if i in states}