Разбор по шагам:
a берёт первый элемент: a = 1,
c берёт последний элемент: c = 5
*b собирает всё, что между: b = [2, 3, 4]
Как работает распаковка
Примеры разных случаев
𝚡 = [𝟷, 𝟸]
*𝚊, 𝚋 = 𝚡 # a = 1, b = 2
𝚢 = [𝟷]
*𝚌, 𝚍 = 𝚢 # c = [ ], d = 1 (остаток пустой!)
𝚣 = [𝟷, 𝟸, 𝟹]
𝚎, *𝚏 = 𝚣 # e = 1, f = [2, 3]
Зачем нужно такое поведение
Подводные камни
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥1
❤2
Важен порядок выполнения цепочки присваиваний.
В Python цепочка присваиваний a = b = c = значение выполняется так:
Для кода Матрешка = Матрешка[0] = ['Матрешка'] выполнение идёт так
Шаг 1: Вычисляется правая часть
Создаётся список ['Матрешка'] — один объект в памяти
Шаг 2: Первое присваивание (слева)
Матрешка = ['Матрешка'] — переменная Матрешка получает ссылку на этот список
Шаг 3: Второе присваивание
Матрешка[0] = ['Матрешка'] — теперь Матрешка уже определена (из шага 2!), и мы можем обратиться к её первому элементу. Первый элемент (строка 'Матрешка') заменяется ссылкой на весь тот же список.
Ключевой момент
Когда выполняется Матрешка[0] = ..., переменная Матрешка уже существует — она была создана на предыдущем шаге цепочки. Поэтому мы можем обратиться к её элементу и заменить строку 'Матрешка' на ссылку на весь список.
Результат: список, который содержит сам себя в качестве первого элемента — рекурсивная структура [[...]].
Подводные камни:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
This media is not supported in your browser
VIEW IN TELEGRAM
Бро, ты можешь тут реализоваться и т.д.
Став частью ОТП Банка, именно ты сделаешь сильнее всю команду! Расти, учись и пробуй новое — это твой шанс создать что-то по-настоящему крутое.
Присоединяйся к ребятам и делись роликом с теми, кто тоже готов к переменам 🚀
Став частью ОТП Банка, именно ты сделаешь сильнее всю команду! Расти, учись и пробуй новое — это твой шанс создать что-то по-настоящему крутое.
Присоединяйся к ребятам и делись роликом с теми, кто тоже готов к переменам 🚀
Что выведет код?
Anonymous Quiz
15%
0 done
42%
0 1 done
31%
0 1 else done
4%
0 1 2 else done
8%
else done
❤2
Разберём код построчно:
Блок
𝚎𝚕𝚜𝚎:
𝚙𝚛𝚒𝚗𝚝("𝚎𝚕𝚜𝚎", 𝚎𝚗𝚍=' ')
выполняется только если цикл завершился «нормально» — то есть перебрал все элементы 𝚛𝚊𝚗𝚐𝚎(𝟹) без выхода через 𝚋𝚛𝚎𝚊𝚔. Здесь цикл прерывается на 𝚒 = 𝟷, поэтому 𝚎𝚕𝚜𝚎 пропускается.
Как про это думать
Полезная ментальная модель: цикл for … else работает почти как «поиск с флагом»:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1
Сегодня попробуем новый формат: вопрос без правильного ответа. Творческий, где есть место рассуждениям вслух.
Допустим, вы создаёте библиотеку для удобного поиска файлов и каких-то действий с ними. Например, надо найти в директории
Задача — сделать это как можно более красиво, лаконично и pythonic way.
Некоторые неплохие вариантыможно посмотреть в этом посте . Кстати, тоже канал по Python, который я веду лично.
Свои варианты интерфейса для обхода файлов с фильтрами кидайте в комментарии. Вместе обсудим плюсы и минусы, будет такая небольшая практика на выходных.
Допустим, вы создаёте библиотеку для удобного поиска файлов и каких-то действий с ними. Например, надо найти в директории
C:\logs все файлы больше 10 МБ с раcширением .log и не старше недели. Если использовать стандартные os.stat и datetime, то получается громоздко.Задача — сделать это как можно более красиво, лаконично и pythonic way.
Некоторые неплохие варианты
Свои варианты интерфейса для обхода файлов с фильтрами кидайте в комментарии. Вместе обсудим плюсы и минусы, будет такая небольшая практика на выходных.
❤4👎1
❤1
Что происходит внутри 𝚏𝚘𝚘():
▸ 𝚙𝚛𝚒𝚗𝚝("𝚏𝚒𝚗𝚊𝚕𝚕𝚢") — на экран выводится первая строка finally.
▸ 𝚛𝚎𝚝𝚞𝚛𝚗 "𝚏𝚒𝚗𝚊𝚕𝚕𝚢" — это новое значение возврата, которое перезаписывает ранее подготовленный 𝚛𝚎𝚝𝚞𝚛𝚗 "𝚝𝚛𝚢".
В итоге 𝚏𝚘𝚘() возвращает "finally".
Что печатает 𝚙𝚛𝚒𝚗𝚝:
Итоговый вывод в терминале: finally finally. То есть первая строка — побочный эффект из 𝚏𝚒𝚗𝚊𝚕𝚕𝚢, вторая — результат возврата функции.
Почему это важно
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Разбор по шагам:
𝚗𝚞𝚖𝚜 = 𝟷, 𝟸, 𝟹, 𝟺, 𝟻, 𝟼, 𝟽, 𝟾, 𝟿 # список чисел от 1 до 9.
𝚗𝚞𝚖𝚜_𝚎𝚟𝚎𝚗 = [] # пустой список для чётных чисел.
𝚏𝚘𝚛 𝚗𝚞𝚖 𝚒𝚗 𝚗𝚞𝚖𝚜: # перебираем каждое число.
▸ 𝚒𝚏 𝚗𝚘𝚝 𝚗𝚞𝚖 % 𝟸: # проверяем чётность (остаток от деления на 2 равен 0).
▸▸ 𝚗𝚞𝚖𝚜_𝚎𝚟𝚎𝚗.𝚊𝚙𝚙𝚎𝚗𝚍(𝚗𝚞𝚖) # добавляем чётные числа: 𝟸, 𝟺, 𝟼, 𝟾.
После цикла:
𝚗𝚞𝚖𝚜_𝚎𝚟𝚎𝚗 = 𝟸, 𝟺, 𝟼, 𝟾 # четыре элемента.
𝚗𝚞𝚖 = 𝟿 # переменная цикла сохраняет последнее значение из 𝚗𝚞𝚖𝚜.
𝚗𝚞𝚖𝚜_𝚎𝚟𝚎𝚗.𝚙𝚘𝚙(𝚗𝚞𝚖) # пытаемся вызвать pop(9).
Метод list.pop(index) принимает индекс, а не значение.
Список имеет длину 4, индексы от 𝟶 до 𝟹, поэтому индекс 𝟹 выходит за границы и вызывает IndexError: pop index out of range.
Вообще говоря pop() удаляет последний элемент, если не указан индекс, но здесь указан индекс 𝚗𝚞𝚖 = 𝟿. Переменная 𝚗𝚞𝚖 после цикла не «сбрасывается», а сохраняет последнее значение, что часто приводит к ошибкам.
— Если нужно удалить последний элемент, следует использовать 𝚗𝚞𝚖𝚜_𝚎𝚟𝚎𝚗.𝚙𝚘𝚙() без аргументов.
— Если нужно удалить по значению, следует использовать 𝚗𝚞𝚖𝚜_𝚎𝚟𝚎𝚗.𝚛𝚎𝚖𝚘𝚟𝚎(𝚗𝚞𝚖).
Кратко выводы
Правило: переменные цикла for в Python не локальны внутри цикла, они остаются в той же области видимости, где был цикл. После цикла for num in nums: переменная num доступна и равна последнему элементу из nums. Это часто приводит к ошибкам, если забыть, что num сохранилась, и использовать её в коде после цикла.
Please open Telegram to view this post
VIEW IN TELEGRAM
✍6
Разбор по шагам в псевдо‑записи:
𝚡 = 𝟷𝟶 — внешняя переменная равна 10.
𝚗𝚞𝚖𝚜 = 𝚡 := 𝚒 𝚏𝚘𝚛 𝚒 𝚒𝚗 𝚛𝚊𝚗𝚐𝚎(𝟸)
— 𝚒 = 𝟶 → 𝚡 := 𝟶 (перезаписывает внешний 𝚡, теперь 𝚡 = 0)
— 𝚒 = 𝟷 → 𝚡 := 𝟷 (перезаписывает внешний 𝚡, теперь 𝚡 = 1)
— 𝚒 = 𝟸 → 𝚡 := 𝟸 (перезаписывает внешний 𝚡, теперь 𝚡 = 2)
Результат: 𝚗𝚞𝚖𝚜 = 𝟶, 𝟷, 𝟸, а внешний 𝚡 = 𝟸.
𝚙𝚛𝚒𝚗𝚝(𝚡, 𝚗𝚞𝚖𝚜) → печатает 2 [0, 1, 2].
Сравнение с обычным list comprehension
> x = 10
> nums = [x for x in range(3)]
> print(x, nums)
Здесь вывод: 10 [0, 1, 2], потому что переменная x внутри comprehension локальна и не затрагивает внешнюю переменную.
Почему это важно
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4