在词典列表中使用“reduce”

时间:2017-02-25 07:07:58

标签: python dictionary functional-programming itertools

我正在尝试编写一个简单的Python函数,该函数将所有具有键的值汇总为 like 。我正在为这项任务进行函数式编程。因此,我需要使用 list-comprehension <html> <style> body{ background-color: black; } a{ border: 5px solid white ; border-radius: 20px; font-size: 50px; position: absolute; bottom: 600px text-decoration: none; color: white; transition: 0.3s ease-in-out; background-color: black; padding: 50px } a:hover { color: white; transition: 0.3s; text-decoration: none; font-size: 53px; } </style> <title>BUTTON TESTING</title> <a href=https://www.youtube.com >F.A.Q.</a> </html> mapfilter。在这种情况下,我认为reduce是一个合理的选择。

reduce

当我实际运行代码时出现问题。我似乎收到了以下内容: TypeError:'int'对象不可订阅。对我来说,这个错误毫无意义。如果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)) 真正迭代了给定的参数,那么传入lambda函数的每个项应该是一个字典 - 并且每个项肯定都有一个 like 键。问题是什么,这个Python错误究竟意味着什么?

5 个答案:

答案 0 :(得分:16)

  

对我来说,这个错误毫无意义。如果reduce实际上是遍历给定参数,那么传入lambda函数的每个项应该是一个字典

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

有两种方法可以解决这个问题。可能更直接的是:

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

0是reduce的“initializer”参数,它为x提供了第一个值。现在,在每个调用中,x是运行总和,y是下一个字典。

另一种方式,只是为了表明它可以完成,是:

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

这使得lambda的返回值成为带有likes键的dict,就像它的参数一样,所以我们在整个过程中使用相同的类型。在这种情况下,这是不必要和浪费的,但如果你聚合了多个密钥,那么这可能是一个有趣的方法。

答案 1 :(得分:3)

根据精确减少的实现方式,在减少传递给lambda的一个操作数的第二次迭代中,不会是dict,而是到目前为止计算的总和。这会让你看到错误。

为了避免这种情况,你可以先做一个列表或生成器理解来提取所有的值,并在#34;喜欢&#34;从各种dicts然后减少operator.add。或者只使用sum。

答案 2 :(得分:3)

在您的代码段reduce(lambda x, y: x["likes"] + y["likes"], msgs)中,x变量首先是列表msgs(dict)的第一个元素,但在第二次迭代时,它将是{{的总和1}}("likes")。

因此,总结喜欢使用int函数docinitializer参数。

reduce

但我相信,使用def sum_favorites(msgs): num_favorites = reduce(lambda x, y: x + y["likes"], msgs, 0) return num_favorites 是一种更加pythonic的方式:

sum

答案 3 :(得分:2)

考虑reduce的工作原理。 x是累加器变量,设置为前一个函数的返回值。

第一次迭代

lambda x, y: x["likes"] + y["likes"] = 40

第二次迭代

lambda 40, y: 40["likes"] + y["likes"] = ???

答案 4 :(得分:0)

在阅读了Paul的回复之后,我意识到为了确保始终如一地总结一致的数据类型,我必须启动reduce以使用int来实现&#39; x&#39 ;以及&#39; y&#39;的字典。因此,

def average_favorites(tweets):
    num_favorites = reduce(lambda x, y: x + y["favorites"], tweets, 0)
    return num_favorites