Python: задачки и вопросы
7.52K subscribers
1.27K photos
2 videos
1 file
118 links
Вопросы и задачки для подготовки к собеседованиям и прокачки навыков

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Другие наши проекты: https://tprg.ru/media
Download Telegram
Please open Telegram to view this post
VIEW IN TELEGRAM
🗿6🤔1
Что выведет код?
Anonymous Quiz
6%
1
69%
3
11%
4
13%
5
1
Оператор * в множественном присваивании собирает «остатки» последовательности в список. Он работает как жадный захват всех элементов между фиксированными переменными.

Разбор по шагам:
🔘𝚡 = [𝟷, 𝟸, 𝟹, 𝟺, 𝟻] # список из 5 элементов
🔘𝚊, *𝚋, 𝚌 = 𝚡 # распаковка с остатком:
a берёт первый элемент: a = 1,
c берёт последний элемент: c = 5
*b собирает всё, что между: b = [2, 3, 4]
🔘𝚙𝚛𝚒𝚗𝚝(𝚕𝚎𝚗(𝚋)) # 3

Как работает распаковка
🔘Переменные без * получают ровно один элемент.
🔘Переменная с * захватывает всё оставшееся (может быть пустым списком).
🔘* можно использовать только один раз в присваивании.

Примеры разных случаев
𝚡 = [𝟷, 𝟸]
*𝚊, 𝚋 = 𝚡 # a = 1, b = 2

𝚢 = [𝟷]
*𝚌, 𝚍 = 𝚢 # c = [ ], d = 1 (остаток пустой!)

𝚣 = [𝟷, 𝟸, 𝟹]
𝚎, *𝚏 = 𝚣 # e = 1, f = [2, 3]

Зачем нужно такое поведение
🔘Элегантно обрабатывать последовательности переменной длины.
🔘Частый паттерн: 𝚏𝚒𝚛𝚜𝚝, *𝚛𝚎𝚜𝚝 = 𝚕𝚒𝚜𝚝 для разделения головы и хвоста.
🔘Работает с любыми итерируемыми объектами: списками, кортежами, строками.

Подводные камни
🔘Если элементов меньше, чем фиксированных переменных, получите ValueError.
🔘* всегда создаёт список, даже если элементов нет.
🔘Можно игнорировать остаток через : 𝚊, *, 𝚋 = [𝟷, 𝟸, 𝟹, 𝟺] → игнорируем середину.
Please open Telegram to view this post
VIEW IN TELEGRAM
3🔥1
Что выведет код?
Anonymous Quiz
40%
['Матрешка']
16%
[[...]]
1%
Боян
43%
Error
2
Это пример создания рекурсивного списка — структуры данных, которая ссылается сама на себя. Python позволяет создавать такие объекты благодаря механизму ссылок.

Важен порядок выполнения цепочки присваиваний.

В Python цепочка присваиваний a = b = c = значение выполняется так:
🔘Сначала вычисляется самое правое выражение (создаётся объект).
🔘Затем присваивания происходят слева направо для каждой цели.

Для кода Матрешка = Матрешка[0] = ['Матрешка'] выполнение идёт так

Шаг 1: Вычисляется правая часть
Создаётся список ['Матрешка'] — один объект в памяти

Шаг 2: Первое присваивание (слева)
Матрешка = ['Матрешка'] — переменная Матрешка получает ссылку на этот список

Шаг 3: Второе присваивание
Матрешка[0] = ['Матрешка'] — теперь Матрешка уже определена (из шага 2!), и мы можем обратиться к её первому элементу. Первый элемент (строка 'Матрешка') заменяется ссылкой на весь тот же список.

Ключевой момент
Когда выполняется Матрешка[0] = ..., переменная Матрешка уже существует — она была создана на предыдущем шаге цепочки. Поэтому мы можем обратиться к её элементу и заменить строку 'Матрешка' на ссылку на весь список.

Результат: список, который содержит сам себя в качестве первого элемента — рекурсивная структура [[...]].

Подводные камни:
🔘Такие структуры нельзя корректно сериализовать в JSON.
🔘Наивное копирование создаст проблемы — нужен 𝚌𝚘𝚙𝚢.𝚍𝚎𝚎𝚙𝚌𝚘𝚙𝚢 с обработкой циклов.
🔘Обход без проверки на посещённые узлы приведёт к бесконечной рекурсии.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
This media is not supported in your browser
VIEW IN TELEGRAM
Бро, ты можешь тут реализоваться и т.д.

Став частью ОТП Банка, именно ты сделаешь сильнее всю команду! Расти, учись и пробуй новое — это твой шанс создать что-то по-настоящему крутое.

Присоединяйся к ребятам и делись роликом с теми, кто тоже готов к переменам 🚀
Главный трюк этой конструкции в том, что else здесь относится не к if, а именно к циклу for. Цикл с else в Python можно читать так: для ... если цикл отработал до конца без break, то выполни ...​

Разберём код построчно:
🔘Старт цикла: 𝚏𝚘𝚛 𝚒 𝚒𝚗 𝚛𝚊𝚗𝚐𝚎(𝟹): — значения 𝚒 будут 𝟶, 𝟷, 𝟸 по очереди.​
🔘Первая итерация: 𝚒 = 𝟶 → выполняется 𝚙𝚛𝚒𝚗𝚝(𝚒, 𝚎𝚗𝚍=' '), на экран уходит 0 .​Условие 𝚒 == 𝟷 ложно, 𝚋𝚛𝚎𝚊𝚔 не выполняется, цикл спокойно переходит к следующему значению.​
🔘Вторая итерация: 𝚒 = 𝟷 → снова 𝚙𝚛𝚒𝚗𝚝(𝚒, 𝚎𝚗𝚍=' '), теперь на экране 0 1. Условие 𝚒 == 𝟷 становится истинным, выполняется 𝚋𝚛𝚎𝚊𝚔, и цикл немедленно прерывается изнутри, не доходя до конца диапазона.​
🔘Что происходит с else:
Блок
𝚎𝚕𝚜𝚎:
𝚙𝚛𝚒𝚗𝚝("𝚎𝚕𝚜𝚎", 𝚎𝚗𝚍=' ')
выполняется только если цикл завершился «нормально» — то есть перебрал все элементы 𝚛𝚊𝚗𝚐𝚎(𝟹) без выхода через 𝚋𝚛𝚎𝚊𝚔. Здесь цикл прерывается на 𝚒 = 𝟷, поэтому 𝚎𝚕𝚜𝚎 пропускается.​
🔘Завершение программы: После цикла всегда выполняется 𝚙𝚛𝚒𝚗𝚝("𝚍𝚘𝚗𝚎"), поэтому к уже напечатанному 0 1 добавляется done, итого вывод: 0 1 done.​

Как про это думать
Полезная ментальная модель: цикл for … else работает почти как «поиск с флагом»:
🔘Если внутри цикла нашлось «что‑то особенное» и вы сделали 𝚋𝚛𝚎𝚊𝚔, 𝚎𝚕𝚜𝚎 не выполняется.​
🔘Если вы честно прошли все элементы и так и не сделали 𝚋𝚛𝚎𝚊𝚔, тогда срабатывает 𝚎𝚕𝚜𝚎 — как ветка «ничего не нашли».
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
Сегодня попробуем новый формат: вопрос без правильного ответа. Творческий, где есть место рассуждениям вслух.

Допустим, вы создаёте библиотеку для удобного поиска файлов и каких-то действий с ними. Например, надо найти в директории C:\logs все файлы больше 10 МБ с раcширением .log и не старше недели. Если использовать стандартные os.stat и datetime, то получается громоздко.

Задача — сделать это как можно более красиво, лаконично и pythonic way.

Некоторые неплохие варианты можно посмотреть в этом посте. Кстати, тоже канал по Python, который я веду лично.

Свои варианты интерфейса для обхода файлов с фильтрами кидайте в комментарии. Вместе обсудим плюсы и минусы, будет такая небольшая практика на выходных.
4👎1