Разбор по шагам в псевдо‑записи:
𝚏𝚞𝚗𝚌𝚜 =
𝚏𝚘𝚛 𝚒 𝚒𝚗 𝚛𝚊𝚗𝚐𝚎(𝟸):
▸ 𝚏𝚞𝚗𝚌𝚜.𝚊𝚙𝚙𝚎𝚗𝚍(𝚕𝚊𝚖𝚋𝚍𝚊 𝚡: 𝚡 * 𝚒)
— создаётся три лямбды, каждая ссылается на переменную i из внешнего scope.
— переменная i меняется: 0 → 1 → 2.
Когда выполняется [f(1) for f in funcs], цикл for i in range(3) уже завершился.
Переменная i в глобальном scope теперь равна 2 (последнее значение).
Первый вызов: funcs[0](1) → lambda x: x * i, где i = 2 → 1 * 2 = 2.
Второй вызов: funcs[1](1) → та же лямбда, та же ссылка на i, i = 2 → 1 * 2 = 2.
Третий вызов: funcs[2](1) → опять i = 2 → 1 * 2 = 2.
Чтобы каждая лямбда «запомнила» своё значение i, нужно захватить его через default argument:
funcs = [lambda x, i=i: x * i for i in range(3)]
print([f(1) for f in funcs]) # [0, 1, 2]
Здесь i=i создаёт локальную переменную внутри лямбды с значением на момент создания, а не ссылкой на внешнюю переменную.
Почему это важно
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6
👍1
Разбор по шагам:
𝚍𝚎𝚏 𝚏():
𝚢𝚒𝚎𝚕𝚍 "𝚊"
𝚢𝚒𝚎𝚕𝚍 "𝚋"
𝚜 = ":".𝚓𝚘𝚒𝚗(𝚏()) — здесь берётся встроенный метод 𝚓𝚘𝚒𝚗, разделителем служит строка ":", а аргументом — генератор.
Генератор по очереди выдаёт "a", потом "b".
— «Собери все строки из генератора, вставь между ними разделитель»
— Результат — строка "a:b".
𝚙𝚛𝚒𝚗𝚝(𝚜) → 'a:b'
Почему это важно
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
Что выведет код?
Anonymous Quiz
28%
[1, 2, 3] [4, 2, 3]
58%
[4, 2, 3] [4, 2, 3]
7%
[1, 2, 3] [1, 2, 3]
7%
Error
👍3
Python сначала вычисляет правую часть целиком: создаётся временный кортеж из текущих значений 𝚢 и 𝟺, то есть [𝟷, 𝟸, 𝟹] и 𝟺.
Только после этого начинается присваивание слева направо:
Но поскольку 𝚡 и 𝚢 указывают на один и тот же список, изменение 𝚢[𝟶] сразу видно и через 𝚡. В итоге список становится [𝟺, 𝟸, 𝟹], и обе переменные выводят его.
Эта задачка показывает важную особенность: порядок вычисления и присваивания в множественном присваивании может приводить к неочевидным результатам, когда левая и правая части «переплетены» через ссылки на изменяемые объекты.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7👎1
Подробный разбор по шагам
Эта задача показывает, что генераторы поддерживают двустороннюю коммуникацию — паттерн, используемый в конвейерах обработки данных и state machines.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Как работает async/await
Асинхронное программирование позволяет программе не простаивать во время долгих операций (сеть, диск, база данных). Ключевое слово 𝚊𝚜𝚢𝚗𝚌 превращает функцию в корутину — объект, который можно «приостановить» на await и потом продолжить, при этом цикл событий в момент ожидания переключается на другие задачи. Для реального запуска корутины нужен либо 𝚊𝚠𝚊𝚒𝚝 внутри другой async‑функции, либо явный вызов через 𝚊𝚜𝚢𝚗𝚌𝚒𝚘.𝚛𝚞𝚗() или цикл событий.
Подробнее
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1