【问题标题】:functools reduce() gives TypeError: 'int' object is not subscriptablefunctools reduce() 给出 TypeError: 'int' object is not subscriptable
【发布时间】:2020-11-02 16:33:02
【问题描述】:

我在使用 functools.reduce() 时遇到问题。 它返回 int 对象不可下标

total_population = functools.reduce(lambda a, b: a[0] + b[0], mid_points)

元组的变量“mid_points”列表:示例如下图所示

但是当我尝试上面的代码行时:

li = [(1,"a"), (2,"b")]

它给出正确的输出,即 3

请帮忙!我在做什么?

【问题讨论】:

  • a[0] + b[0] 返回一个 int,它将作为 a 输入到下一次迭代中......

标签: python python-3.x list reduce functools


【解决方案1】:

reduce 的结果需要是归约函数的有效输入;您的归约函数需要一个至少包含一个元素的序列,但您返回的是 int。只需将代码更改为:

[total_population] = functools.reduce(lambda a, b: (a[0] + b[0],), mid_points)

添加一层tuple 包装,以便索引继续工作,brackets at the end unpack the resulting single element tuple.如果mid_points 是单个元素,这将中断,所以如果可能的话:

total_population, *_ = functools.reduce(lambda a, b: (a[0] + b[0],), mid_points)

稍微安全一些,因为它只是将结果中的任何额外元素捕获到被忽略的list中。

另一种选择(感谢@deceze 提醒我)是给reduce 一个起始值,所以a 始终是int,无论是第一次调用还是所有后续调用:

total_population = functools.reduce(lambda a, b: a + b[0], mid_points, 0)

reduce 的最后一个参数是第一个 a,所有后续的 as 都是先前调用的结果。当然,这也可以通过第三种方式简化,完全避免reduce

from operator import itemgetter

total_population = sum(map(itemgetter(0), mid_points))

# Or without an import, but ever-so-slightly slower:
total_population = sum(pt[0] for pt in mid_points)

因为你真的只需要做两件事;提取每个输入的第一个元素,并将它们相加。

【讨论】:

  • 我宁愿为reduce 添加一个起始参数,以确保a始终是一个整数……
  • @deceze:当然。我会补充的。
  • 谢谢!终于明白我的代码出了什么问题。
猜你喜欢
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
  • 2022-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多