functools reduce () выдает TypeError: объект int не подлежит подписке - PullRequest
0 голосов
/ 13 июля 2020

У меня проблема с functools.reduce (). Он возвращает int, объект не подлежит подписке

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

переменная 'mid_points' список кортежей: образец приведен на рисунке ниже

Но когда я попробовал строку кода выше:

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

дает правильный результат, т.е. 3

Пожалуйста, помогите! что мне делать?

образец mid_points

1 Ответ

1 голос
/ 13 июля 2020

Результат reduce должен быть действительным входным для функции сокращения; ваша функция сокращения ожидает последовательность по крайней мере с одним элементом, но вы возвращаете int. Просто измените код на:

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

, чтобы добавить слой tuple обертывания, чтобы индексация продолжала работать, а скобки в конце распаковывают полученный единственный элемент 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, а все последующие a являются результатами предыдущих вызовов. Конечно, это также можно упростить третьим способом, чтобы полностью избежать 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)

, поскольку на самом деле вам просто нужно сделать две вещи; извлеките первый элемент каждого ввода и просуммируйте их.

...