[英]Using reduce on a list of dictionaries of dictionaries
Here is the given list. 这是给定的列表。
Pets = [{'f1': {'dogs': 2, 'cats': 3, 'fish': 1},
'f2': {'dogs': 3, 'cats': 2}},
{'f1': {'dogs': 5, 'cats': 2, 'fish': 3}}]
I need to use the map and reduce function so that I can have a final result of 我需要使用map和reduce函数,以便我可以得到最终结果
{'dogs': 10, 'cats': 7, 'fish': 4}
I have written a function using map 我用地图写了一个函数
def addDict(d):
d2 = {}
for outKey, inKey in d.items():
for inVal in inKey:
if inVal in d2:
d2[inVal] += inKey[inVal]
else:
d2[inVal] = inKey[inVal]
return d2
def addDictN(L):
d2 = list(map(addDict, L))
print(d2)
That returns 那回来了
[{'dogs': 5, 'cats': 5, 'fish': 1}, {'dogs': 5, 'cats': 2, 'fish': 3}]
It combines the f1 and f2 of the first and second dictionaries, but I am unsure of how to use reduce on the dictionaries to get the final result. 它结合了第一和第二个词典的f1和f2,但我不确定如何在词典中使用reduce来获得最终结果。
You can use collections.Counter
to sum your list of counter dictionaries. 您可以使用
collections.Counter
计数器词典列表。
Moreover, your dictionary flattening logic can be optimised via itertools.chain
. 此外,您的字典展平逻辑可以通过
itertools.chain
进行优化。
from itertools import chain
from collections import Counter
Pets = [{'f1': {'dogs': 2, 'cats': 3, 'fish': 1},
'f2': {'dogs': 3, 'cats': 2}},
{'f1': {'dogs': 5, 'cats': 2, 'fish': 3}}]
lst = list(chain.from_iterable([i.values() for i in Pets]))
lst_sum = sum(map(Counter, lst), Counter())
# Counter({'cats': 7, 'dogs': 10, 'fish': 4})
This works for an arbitrary length list of dictionaries, with no key matching requirements across dictionaries. 这适用于任意长度的字典列表,字典中没有键匹配要求。
The second parameter of sum
is a start value. sum
的第二个参数是起始值。 It is set to an empty Counter object to avoid TypeError
. 它被设置为一个空的Counter对象以避免
TypeError
。
Without using map
and reduce
, I would be inclined to do something like this: 不使用
map
和reduce
,我倾向于做这样的事情:
from collections import defaultdict
result = defaultdict()
for fdict in pets:
for f in fdict.keys():
for pet, count in fdict[f].items():
result[pet] += count
Using reduce
(which really is not the right function for the job, and is not in Python 3) on your current progress would be something like this: 在当前进度中使用
reduce
(对于作业来说真的不是正确的函数,而不是在Python 3中)将是这样的:
from collections import Counter
pets = [{'dogs': 5, 'cats': 5, 'fish': 1}, {'dogs': 5, 'cats': 2, 'fish': 3}]
result = reduce(lambda x, y: x + Counter(y), pets, Counter())
You can use purely map
and reduce
like so: 你可以像这样使用纯粹的
map
和reduce
:
Pets = [{'f1': {'dogs': 2, 'cats': 3, 'fish': 1},
'f2': {'dogs': 3, 'cats': 2}},
{'f1': {'dogs': 5, 'cats': 2, 'fish': 3}}]
new_pets = reduce(lambda x, y:[b.items() for _, b in x.items()]+[b.items() for _, b in y.items()], Pets)
final_pets = dict(reduce(lambda x, y:map(lambda c:(c, dict(x).get(c, 0)+dict(y).get(c, 0)), ['dogs', 'cats', 'fish']), new_pets))
Output: 输出:
{'fish': 4, 'cats': 7, 'dogs': 10}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.