Как вернуть новый словарь, если ключи в одном словаре совпадают с ключами в другом словаре?
В настоящее время у меня есть словарь, ключ которого представляет собой почтовый индекс, а значения также являются словарем.
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}