Список карт по частичной функции vs lambda
Мне было интересно, для большинства примеров более "pythonic" использовать lambda
или partial
функция?
Например, я могу применить imap
в каком-либо списке, например добавить 3 к каждому элементу, используя:
imap(lambda x : x + 3, my_list)
Или использовать partial
:
imap(partial(operator.add, 3), my_list)
Я понимаю, что в этом примере цикл, возможно, облегчит его, но я думаю о более нетривиальных примерах.
В Haskell я бы легко выбрал частичное приложение в приведенном выше примере, но я не уверен в Python. Для меня лямбда кажется лучшим выбором, но я не знаю, какой преобладающий выбор для большинства программистов на питоне.
Ответы
Ответ 1
Чтобы быть действительно эквивалентным imap
, используйте выражение генератора:
(x + 3 for x in mylist)
Подобно imap
, это не сразу создает весь новый список, а вместо этого вычисляет элементы результирующей последовательности по запросу (и, таким образом, намного эффективнее, чем понимание списка, если вы привязываете результат к другому итерации).
Если вам интересно, где partial
будет лучшим вариантом, чем lambda
в реальном мире, это, как правило, когда вы имеете дело с переменным числом аргументов:
>>> from functools import partial
>>> def a(*args):
... return sum(args)
...
>>> b = partial(a, 2, 3)
>>> b(6, 7, 8)
26
Эквивалентная версия с использованием lambda
будет...
>>> b = lambda *args: a(2, 3, *args)
>>> b(6, 7, 8)
26
который немного менее кратким, но lambda
дает вам возможность приложения не по порядку, которое partial
не выполняет:
>>> def a(x, y, z):
... return x + y - z
...
>>> b = lambda m, n: a(m, 1, n)
>>> b(2, 5)
-2
Ответ 2
В данном примере лямбда представляется наиболее подходящей. Это также легче на глазах.
Я никогда не видел использования частичных функций в дикой природе.
Ответ 3
lambda, безусловно, во много раз чаще встречается. Если вы не выполняете функциональное программирование в академических условиях, вы, вероятно, должны уклоняться от functools.
Это pythonic. Никакая библиотека не нужна или даже встроенная, просто простое выражение генератора.
( x + 3 for x in my_list )
Это создает генератор, аналогичный imap.
Если вы все равно сделаете список, используйте вместо этого понимание списка:
[ x + 3 for x in my_list ]