2008-10-08 2 views
58

Кажется, в сети много обсуждений об изменениях функции reduce() в python 3.0 и способах ее удаления. Мне трудно понять, почему это так; Я считаю вполне разумным использовать его в самых разных случаях. Если презрение было просто субъективным, я не могу себе представить, что такое большое количество людей позаботится об этом.В чем проблема с сокращением()?

Что мне не хватает? В чем проблема с сокращением()?

ответ

62

Как Гвидо говорит в своем The fate of reduce() in Python 3000 пост:

Так что теперь уменьшить(). Это на самом деле тот, которого я всегда ненавидел больше всего, потому что, помимо нескольких примеров с участием + или *, почти каждый раз, когда я вижу вызов reduce() с нетривиальным аргументом функции, мне нужно захватить ручку и бумагу диаграмму, что на самом деле подается в эту функцию, прежде чем я пойму, что должен делать метод reduce(). Поэтому, на мой взгляд, применимость reduce() в значительной степени ограничена ассоциативными операторами, и во всех остальных случаях лучше написать цикл накопления явно.

Существует отличный пример запутанной reduce в Functional Programming HOWTO статье:

Быстрый, что это следующий код делает?

total = reduce(lambda a, b: (0, a[1] + b[1]), items)[1] 

Вы можете понять это, но это требует времени, чтобы распутать выражение, чтобы выяснить , что происходит. Используя короткое вложенное DEF заявления делает вещи немного лучше:

def combine (a, b): 
    return 0, a[1] + b[1] 

total = reduce(combine, items)[1] 

Но было бы лучше всего, если бы я просто использовал для цикла:

total = 0 
for a, b in items: 
    total += b 

Или сумма() встроенными in и выражение генератора:

total = sum(b for a,b in items) 

Многие виды использования reduce() более ясны при написании как для циклов.

8

Люди обеспокоены тем, что поощряют запутанный стиль программирования, делая что-то, что может быть достигнуто с помощью более ясных методов.

Я не против уменьшения себя, я также иногда нахожу его полезным инструментом.

31

reduce() не удаляется - он просто перемещается в модуль functools. Мысль Гвидо заключается в том, что, за исключением тривиальных случаев, таких как суммирование, код, написанный с использованием reduce(), обычно более ясен, когда записывается как цикл накопления.

+24

Gah, это ужасная аргументация :( – TraumaPony 2008-10-08 07:22:33

+16

Является ли это? Много философии Python - это четкий и понятный код. Типичный вызов для сокращения() обычно требует, чтобы я вырвал карандаш и нарисуйте, что функция с. – 2008-10-08 07:57:22

1

Основная причина существования сокращения - избегать написания явных для петель с аккумуляторами. Несмотря на то, что у python есть некоторые возможности для поддержки функционального стиля, это не рекомендуется. Если вам нравится «реальный», а не «питонический» функциональный стиль, вместо этого используйте современный Lisp (Clojure?) Или Haskel.