какие функциональные инструменты остались в Python 3k?
-
08-07-2019 - |
Вопрос
Я прочитал несколько записей, касающихся удаления нескольких функциональных функций из будущего python, включая map и reduce.
Какова официальная политика в отношении функциональных расширений?
останется ли лямбда-функция?
Решение
Ну, Python 3.0 и 3.1 уже выпущены, так что вы можете проверить это сами. Конечным результатом было то, что карта и фильтр были сохранены как встроенные, и лямбда также была сохранена. Единственным изменением было то, что сокращение было перенесено в модуль functools; вам просто нужно сделать
from functools import reduce
использовать его.
Ожидается, что будущие выпуски 3.x останутся обратно совместимыми с 3.0 и 3.1 в этом отношении.
Другие советы
В Python 3.x в Python по-прежнему встроен богатый набор функциональных инструментов:представления списков, выражения-генераторы, итераторы и генераторы, а также такие функции, как any()
и all()
которые имеют оценку короткого замыкания везде, где это возможно.
"Пожизненный доброжелательный диктатор Python" выдвинул идею удаления map()
потому что вы можете тривиально воспроизвести его эффекты с помощью понимания списка:
lst2 = map(foo, lst)
lst3 = [foo(x) for x in lst]
lst2 == lst3 # evaluates True
Питоновский lambda
функция не была удалена или переименована и, скорее всего, никогда не будет.Однако и она, скорее всего, никогда не станет более мощной.Питоновский lambda
ограничивается одним выражением;он не может включать инструкции и не может включать несколько строк кода Python.
Простой старый стандарт Python def
определяет функциональный объект, который может передаваться так же легко, как lambda
объект.Вы даже можете отменить привязку имени функции после ее определения, если вы действительно хотите это сделать.
Пример:
# NOT LEGAL PYTHON
lst2 = map(lambda x: if foo(x): x**2; else: x, lst)
# perfectly legal Python
def lambda_function(x):
if foo(x):
return x**2
else:
return x
lst2 = map(lambda_function, lst)
del(lambda_function) # can unbind the name if you wish
Обратите внимание, что на самом деле вы могли бы использовать "троичный оператор" в lambda
таким образом, приведенный выше пример немного надуман.
lst2 = map(lambda x: x**2 if foo(x) else x, lst)
Но некоторые многострочные функции трудно внедрить в lambda
и лучше обрабатываются как простые обычные многострочные функции.
Python 3.x не утратил ни капли своей функциональной мощи.Существует некоторое общее мнение, что понимание списков и выражений генератора, вероятно, предпочтительнее, чем map()
;в частности, выражения генератора иногда могут использоваться для выполнения эквивалента map()
но без выделения списка, а затем повторного его освобождения.Например:
total = sum(map(lst, foo))
total2 = sum(foo(x) for x in lst)
assert total == total2 # same result
В Python 2.x map()
выделяет новый список, который суммируется и сразу же освобождается.Выражение генератора получает значения по одному за раз и никогда не связывает память с целым списком значений.
В Python 3.x, map()
является "ленивым", поэтому оба примерно одинаково эффективны.Но в результате в Python 3.x троичный пример лямбды должен быть принудительно развернут в список:
lst2 = list(map(lambda x: x**2 if foo(x) else x, lst))
Проще просто написать список для понимания!
lst2 = [x**2 if foo(x) else x for x in lst]