lambda - это способ создания безымянных функций. Например, f = lambda x: x**2 создает функцию, которая возводит число в квадрат. Если мы вызовем f(4), то получим 16. В данном случае, f является указателем на безымянную функцию с одним параметром. Аналогично, в твоем коде функция myfunc возвращает безымянную функцию, которая умножает значение на аргумент n. Если мы вызовем данную функцию с аргументом a=11, то получим результат 22. Эта безымянная функция находится после оператора return функции myfunc, то есть myfunc вернет результат выполнения данной безымянной функции. Ошибка в твоей логике заключается в том, что myfunc возвращает функцию, а не вычисляет ее только вместо n. Теперь о программа доходит до строки print(mydoubler(11)). Чтобы напечатать результат выполнения функции mydoubler, программа вызывает данную функцию с аргументом 11. Для этого она идет к строке mydoubler = myfunc(2). Она не возвращает назад по коду. Сначала отрабатывает оператор def, который определяет функцию myfunc. Затем в текущей области видимости программы появляется переменная myfunc, которая содержит ссылку на объект-функцию. Затем отрабатывает строка mydoubler = myfunc(2). В этой строке происходит вызов функции myfunc с параметром 2. Внутри области видимости myfunc появляется переменная a, которая ссылается на объект-число 2. Создается лямбда-функция, которая ссылается на данный параметр. Лямбда-функция возвращается из myfunc, и myfunc завершает свое выполнение. Так как лямбда-функция продолжает существовать (она была возвращена), и она ссылается на объект-число 2, то этот объект также продолжает существовать. Возвращенная функция присваивается имени mydoubler в текущей области видимости. Это позволяет продолжать ее использование и вызывать по данному имени. Если бы мы добавили еще один вызов, например mytripler = myfunc(3), то это создало бы новую лямбда-функцию, независимую от mydoubler, и ссылалась бы на объект-число 3.