在词典列表上使用“ reduce”


问题内容

我正在尝试编写一个简单的Python函数,该函数将所有具有键的值相加为 like 。我正在为此功能编程。因此,我需要使用一个 列表理解
mapfilter,或reduce。在这种情况下,我认为减少是一个合理的选择。

def sum_favorites(msgs):
     num_favorites = reduce(lambda x, y: x["likes"] + y["likes"], msgs)
     return num_favorites


content1 = {"likes": 32, ...}
content2 = {"likes": 8, ...}
content3 = {"likes": 16, ...}
contents = [content1, content2, content3]
print(sum_favorites(contents))

问题出在我实际运行代码时。我似乎收到一些类似的东西: TypeError:’int’对象不可下标
。对我来说,这个错误是没有道理的。如果reduce确实要通过给定的参数进行迭代,则传递给lambda函数的每个项目都应该是一个词典-
并且每个项目中肯定都有一个 likes 键。这是什么问题,这个Python错误究竟意味着什么?


问题答案:

对我来说,这个错误是没有道理的。如果reduce确实是通过给定的参数进行迭代,则传递给lambda函数的每个项目都应该是一个字典

否,传递给lambda的 第一个
参数(对于除第一个调用之外的所有调用)是前一次调用到lambda的返回值。您的函数返回一个数字,因此将其x作为数字而不是字典进行调用。

有两种解决方法。可能更直接的一种是:

num_favorites = reduce(lambda x, y: x + y['likes'], msgs, 0)

0是“初始化”参数减少,这提供了所述第一值x。现在在每个调用中,x是运行总和,y是下一个字典。

只是为了表明可以做到的另一种方法是:

result = reduce(lambda x, y: { 'likes': x['likes'] + y['likes'] }, msgs)
num_favorites = result['likes']

likes就像它的参数一样,这使得lambda的返回值成为带有键的字典,因此我们一直在使用相同的类型。在这种情况下,这是不必要和浪费的,但是如果您要聚集多个密钥,这可能是一种有趣的方法。