Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 4, 2019 21:30:11

first-step
Зарегистрирован: 2015-09-21
Сообщения: 36
Репутация: +  0  -
Профиль   Отправить e-mail  

Прошу помощи в разборе с лямбда функцией

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

Предлагаю начать с разбора найденной на другом сайте строки с участием этих чертовок:
map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), range(10))
Насколько я сейчас понимаю ситуацию, то лямбда функция имеет стандартную запись, например:
map(lambda x: x + 1, range(a))

По моим соображениям в этой записи все устоено так:
- объявляется функция lambda
- указывается условное название элемента итерируемого объекта в формулах функции, в данном случае “х”
- далее идет двоеточие “:” говорящее, что далее будет собственно описание действий функции
- далее идет само описание действия
- далее запятая, говорящая, что описание функции кончилось
- далее идет ссылка на итерируемый объект, элементы которого, под условным названием “х”, будут подвергаться экзекуции.

Обладая таким представлением я попытался разобраться, как работает строка, которая упоминалась выше….и понял, что я что то не понимаю в этой ситуации…
если с первым упоминанием lambda функции еще более-менее ясно, что есть аргумент n, есть некое описание фунции и после запятой есть итерируемый объект range(10)
map(
lambda n:
(lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n),
range(10)
)

то при детальном рассмотрении второго упоминания lambda функции я попал в ступор…совсем не понял запись:
lambda f, *a: f(f, *a)
Если не будет возражений, то именно с этого места и начнем…. Кто нибудь знает, как объяснить сию запись?

Отредактировано first-step (Апрель 4, 2019 21:33:48)

Офлайн

#2 Апрель 5, 2019 02:04:25

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10024
Репутация: +  857  -
Профиль   Отправить e-mail  

Прошу помощи в разборе с лямбда функцией

Для начала нужно разделить понятия лямбда-функции и лямбда-функции, реализованной в питоне. В питоне она однострочная, тогда как в общем определении (для всех языков программирования) такого ограничения нет.

Дальше в питоне у функций есть свои, питоновские синтаксические конструкции, которых нет в других языках. В частности здесь это видно по *a. Так что эти вещи к лямбда-функциям вообще не относятся.

В-третьих, передача функции в функцию - это вообще отдельный вопрос, который точно так же не имеет отношения к лямбда-функциям.

Также тут используется рекурсия, которая тоже к лямбда-функциям не относится.

Так что понять ты не можешь следующие понятия:
1) разница между лямбда-функцией, лямбда-функцией в питоне и лямбда-выражением в питоне;
2) распаковка аргументов функции в питоне;
3) функции как объекты первого класса;
4) рекурсивные вызовы функций.


Например, map() может принимать любую функцию, поэтому она может принимать и лямбда-функцию, так как лямбда-функция ничем не отличается от любой другой функции, у неё только имени нет. Лямбда-функцию можно создать отдельно и передать её в map() через ссылку, а можно создать динамически прямо на месте с помощью лямбда-выражения. Лямбда-выражение создаёт лямбда-функцию, поэтому результат лямбда-выражения можно сразу вызвать как функцию.

Вот пример

  
>>> res = (lambda x: x * 2)(5)
>>> res
10
>>>
Используется лямбда-функция в лямбда-выражении, где результат лямбда-выражения - определённая на время лямбда-функция - сразу вызывается с аргументом и возвращаемое значение из лямбда-функции присваивается переменной.


tags: lambda



Отредактировано py.user.next (Апрель 5, 2019 02:11:59)

Офлайн

#3 Апрель 5, 2019 09:12:06

first-step
Зарегистрирован: 2015-09-21
Сообщения: 36
Репутация: +  0  -
Профиль   Отправить e-mail  

Прошу помощи в разборе с лямбда функцией

Спасибо за подробный ответ. Конечно я говорю про питон. Видимо его синтаксис я еще не выучил, поэтому меня заставила задуматься запись f(f, *a) … никогда с таким не сталкивался. Особенно в частности f(f Простите, а где почитать можно про это?

Или такая конструкция связана с записью lambda f…в частности f
может быть именно эта?

Отредактировано first-step (Апрель 5, 2019 09:30:47)

Офлайн

#4 Апрель 5, 2019 10:00:19

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10024
Репутация: +  857  -
Профиль   Отправить e-mail  

Прошу помощи в разборе с лямбда функцией

first-step
Особенно в частности f(f Простите, а где почитать можно про это?
Это передача функции в функцию. Отношения к лямбда-функциям нет никакого.
  
>>> def f(func1, func2):
...     print('function1 is', func1)
...     print('function2 is', func2, 'call result is', func2())
... 
>>> def g():
...     return 2 * 2
... 
>>> f(f, g)
function1 is <function f at 0x7f73dc83fea0>
function2 is <function g at 0x7f73d4672620> call result is 4
>>> 
>>> f(print, lambda: 1)
function1 is <built-in function print>
function2 is <function <lambda> at 0x7f73d4672620> call result is 1
>>>
>>> f(print, list)
function1 is <built-in function print>
function2 is <class 'list'> call result is []
>>>

wiki. функции первого класса
wiki. объект первого класса



Отредактировано py.user.next (Апрель 5, 2019 10:06:35)

Офлайн

#5 Апрель 5, 2019 13:08:10

first-step
Зарегистрирован: 2015-09-21
Сообщения: 36
Репутация: +  0  -
Профиль   Отправить e-mail  

Прошу помощи в разборе с лямбда функцией

py.user.next
Это передача функции в функцию
Спасибо, передачу функции в функцию слышал, но не внимательно, сейчас плотнее изучу.

Но, пока не понял запись lambda f, *a: f(f, *a) Откуда взялась функция с названием f? Неужели текст lambda f, *a: f(f, *a) содержит в себе информацию, что мало того, что появился аргумент f, но и, что самое интересное, появилась функция f теперь? Ведь запись f(f, *a) - это не что иное, как вызов функции f?

Отредактировано first-step (Апрель 5, 2019 13:10:34)

Офлайн

#6 Апрель 5, 2019 14:43:19

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10024
Репутация: +  857  -
Профиль   Отправить e-mail  

Прошу помощи в разборе с лямбда функцией

first-step
Откуда взялась функция с названием f?
f - это просто имя аргумента. Это так же, как и в примере выше, имя func1 или func2 - это имена аргументов функции.

Можно сделать так
 lambda arg1, *arg2: arg1(arg1, *arg2)

  
>>> (lambda arg1, *arg2: arg1(arg1, *arg2))(print, 1, 2, 3)
<built-in function print> 1 2 3
>>>



Отредактировано py.user.next (Апрель 5, 2019 14:46:12)

Офлайн

#7 Апрель 5, 2019 15:29:48

first-step
Зарегистрирован: 2015-09-21
Сообщения: 36
Репутация: +  0  -
Профиль   Отправить e-mail  

Прошу помощи в разборе с лямбда функцией

Вот в предыдущем примере мне как раз все понятно. Все по-людски. Есть объявление def и т.д

А вот в записи

 lambda arg1, *arg2: arg1(arg1, *arg2)
не понятно ничего….
В чем логика? До двоеточия - идет перечисление аргументов? Т.е. аргументы lambda-функции - это arg1 и *arg2, а после двоеточия что?
arg1(arg1, *arg2) - что за запись? . У аргумента arg1 теперь есть свои аргументы (arg1 и *arg2). arg1 - каким то образом в функцию превратился?

Офлайн

#8 Апрель 5, 2019 15:46:30

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10024
Репутация: +  857  -
Профиль   Отправить e-mail  

Прошу помощи в разборе с лямбда функцией

first-step
До двоеточия - идет перечисление аргументов?
Да, это перечисление аргументов функции.

first-step
а после двоеточия что?
После двоеточия идёт однострочное тело функции. Тело функции срабатывает, когда функцию вызываешь.

first-step
arg1 - каким то образом в функцию превратился?
В эту функцию подали функцию. Поданная функция прикрепилась к аргументу и аргумент стал функцией. Дальше аргумент вызывается, потому что это функция. А в вызов этой функции подаётся этот же аргумент. Это как в функцию print() подать функцию print().

  
>>> print(print, print, print)
<built-in function print> <built-in function print> <built-in function print>
>>>



Офлайн

#9 Апрель 5, 2019 16:00:10

first-step
Зарегистрирован: 2015-09-21
Сообщения: 36
Репутация: +  0  -
Профиль   Отправить e-mail  

Прошу помощи в разборе с лямбда функцией

Подождите, подождите… Уже близко решение)

py.user.next
В эту функцию подали функцию. Поданная функция прикрепилась к аргументу и аргумент стал функцией. Дальше аргумент вызывается, потому что это функция. А в вызов этой функции подаётся этот же аргумент. Это как в функцию print() подать функцию print().

В функцию print, подать функцию print - это мне понятно. Функция print где то в самом питоне определена как функция. А вот arg1 в какую секунду превратился в функцию? или любая запись типа a(b) - превращает a в функцию?


Офлайн

#10 Апрель 5, 2019 16:06:37

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10024
Репутация: +  857  -
Профиль   Отправить e-mail  

Прошу помощи в разборе с лямбда функцией

first-step
А вот arg1 в какую секунду превратился в функцию?
Когда функцию вызвали и передали в вызов на место аргумента функцию. Вот я думаю, что ты просто не понимаешь разницы между определением функции и вызовом функции. Поэтому ты не можешь понять, где определение лямбда-функции, а где вызов лямбда-функции.

first-step
или любая запись типа a(b) - превращает a в функцию?
Круглые скобки вызывают тот объект, к которому привязано имя a, как функцию.

  
>>> a = 1
>>> 
>>> a('x')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> 
>>> a = print
>>> 
>>> a('x')
x
>>>



Отредактировано py.user.next (Апрель 5, 2019 16:07:29)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version