fa
Feedback
Python: задачки и вопросы

Python: задачки и вопросы

رفتن به کانال در Telegram

Вопросы и задачки для подготовки к собеседованиям и прокачки навыков Разместить рекламу: @tproger_sales_bot Правила общения: https://tprg.ru/rules Другие каналы: @tproger_channels Другие наши проекты: https://tprg.ru/media

نمایش بیشتر
6 963
مشترکین
+124 ساعت
-67 روز
-6130 روز
آرشیو پست ها
Что выведет код?
Anonymous voting

Главная идея: в конструкции try/except/finally блок finally выполняется всегда — и перед выходом из функции, и при исключениях, и даже если в try уже выполнен return. При этом return внутри finally имеет приоритет и заменяет любое ранее вычисленное значение возврата. Что происходит внутри 𝚏𝚘𝚘(): 🔘Заходим в блок 𝚝𝚛𝚢, выполняется 𝚛𝚎𝚝𝚞𝚛𝚗 "𝚝𝚛𝚢" — Python запоминает, что функция должна вернуть "try", но перед реальным выходом обязан выполнить 𝚏𝚒𝚗𝚊𝚕𝚕𝚢. 🔘Заходим в блок 𝚏𝚒𝚗𝚊𝚕𝚕𝚢: ▸ 𝚙𝚛𝚒𝚗𝚝("𝚏𝚒𝚗𝚊𝚕𝚕𝚢") — на экран выводится первая строка finally. ▸ 𝚛𝚎𝚝𝚞𝚛𝚗 "𝚏𝚒𝚗𝚊𝚕𝚕𝚢" — это новое значение возврата, которое перезаписывает ранее подготовленный 𝚛𝚎𝚝𝚞𝚛𝚗 "𝚝𝚛𝚢". В итоге 𝚏𝚘𝚘() возвращает "finally". Что печатает 𝚙𝚛𝚒𝚗𝚝: 🔘Внутри 𝚏𝚘𝚘(): печатается finally. 🔘Снаружи: 𝚙𝚛𝚒𝚗𝚝(𝚏𝚘𝚘()) печатает возвращённое значение "finally". Итоговый вывод в терминале: finally finally. То есть первая строка — побочный эффект из 𝚏𝚒𝚗𝚊𝚕𝚕𝚢, вторая — результат возврата функции. Почему это важно 🔘𝚏𝚒𝚗𝚊𝚕𝚕𝚢 всегда выполняется: при нормальном завершении, при return, при исключении. 🔘𝚛𝚎𝚝𝚞𝚛𝚗 внутри 𝚏𝚒𝚗𝚊𝚕𝚕𝚢 перетирает результат 𝚝𝚛𝚢/𝚎𝚡𝚌𝚎𝚙𝚝, поэтому так писать опасно: легко скрыть реальные ошибки или неожиданные возвраты. 🔘Рекомендуется не использовать 𝚛𝚎𝚝𝚞𝚛𝚗 в 𝚏𝚒𝚗𝚊𝚕𝚕𝚢; лучше ограничиваться чистым cleanup — закрытием файлов, соединений и т.п.

Что выведет код?
Anonymous voting

Сегодня попробуем новый формат: вопрос без правильного ответа. Творческий, где есть место рассуждениям вслух. Допустим, вы со
Сегодня попробуем новый формат: вопрос без правильного ответа. Творческий, где есть место рассуждениям вслух. Допустим, вы создаёте библиотеку для удобного поиска файлов и каких-то действий с ними. Например, надо найти в директории C:\logs все файлы больше 10 МБ с раcширением .log и не старше недели. Если использовать стандартные os.stat и datetime, то получается громоздко. Задача — сделать это как можно более красиво, лаконично и pythonic way. Некоторые неплохие варианты можно посмотреть в этом посте. Кстати, тоже канал по Python, который я веду лично. Свои варианты интерфейса для обхода файлов с фильтрами кидайте в комментарии. Вместе обсудим плюсы и минусы, будет такая небольшая практика на выходных.

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

Что выведет код?
Anonymous voting

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

Это пример создания рекурсивного списка — структуры данных, которая ссылается сама на себя. Python позволяет создавать такие объекты благодаря механизму ссылок. Важен порядок выполнения цепочки присваиваний. В Python цепочка присваиваний a = b = c = значение выполняется так: 🔘Сначала вычисляется самое правое выражение (создаётся объект). 🔘Затем присваивания происходят слева направо для каждой цели. Для кода Матрешка = Матрешка[0] = ['Матрешка'] выполнение идёт так Шаг 1: Вычисляется правая часть Создаётся список ['Матрешка'] — один объект в памяти Шаг 2: Первое присваивание (слева) Матрешка = ['Матрешка'] — переменная Матрешка получает ссылку на этот список Шаг 3: Второе присваивание Матрешка[0] = ['Матрешка'] — теперь Матрешка уже определена (из шага 2!), и мы можем обратиться к её первому элементу. Первый элемент (строка 'Матрешка') заменяется ссылкой на весь тот же список. Ключевой момент Когда выполняется Матрешка[0] = ..., переменная Матрешка уже существует — она была создана на предыдущем шаге цепочки. Поэтому мы можем обратиться к её элементу и заменить строку 'Матрешка' на ссылку на весь список. Результат: список, который содержит сам себя в качестве первого элемента — рекурсивная структура [[...]]. Подводные камни: 🔘Такие структуры нельзя корректно сериализовать в JSON. 🔘Наивное копирование создаст проблемы — нужен 𝚌𝚘𝚙𝚢.𝚍𝚎𝚎𝚙𝚌𝚘𝚙𝚢 с обработкой циклов. 🔘Обход без проверки на посещённые узлы приведёт к бесконечной рекурсии.

Что выведет код?
Anonymous voting

Уже сегодня через несколько часов начнется конференция «Проектная исповедь» — о том, как жить, работать и ошибаться в мире ди
Уже сегодня через несколько часов начнется конференция «Проектная исповедь» — о том, как жить, работать и ошибаться в мире дилемм. Всего вас ждет 8 выступлений, кратко расскажем, что к чему 12:10 — Сергей Кожемякин поведает "Исповедь контрол‑фрика: как подчинить тревожность и использовать её в работе" 12:35 — Анна Аксенова поделится, как "Создать из хаоса порядок, или как сверить несверяемое" 13:00 — Алексей Мостовщиков и Андрей Лупий дадут инструкцию по применению GR в ИТ 13:25 — Яна Федорова расскажет, как "Промолчать ради гармонии или говорить о проблемах" 13:50 — Александр Ряховский поможет найти баланс контроля и вдохновения на выступлении "Искусство управлять невозможным" 14:15 — Дмитрий Урузгалиев построит "Мосты вместо стен: как соединить работу и жизнь, не сгорев на границе" 14:40 — Алексей Шершнев объяснит, "Что на самом деле убивает ИТ‑проекты" 15:05 — Иван Москвин покажет, как "Кастомизировать продукт под каждого или делать универсальное решение" Конференция бесплатная, но надо зарегистрироваться. Сделать это можно на красивом лендинге: https://tprg.ru/KkLb Это #партнёрский пост

Оператор * в множественном присваивании собирает «остатки» последовательности в список. Он работает как жадный захват всех элементов между фиксированными переменными. Разбор по шагам: 🔘𝚡 = [𝟷, 𝟸, 𝟹, 𝟺, 𝟻] # список из 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. 🔘* всегда создаёт список, даже если элементов нет. 🔘Можно игнорировать остаток через : 𝚊, *, 𝚋 = [𝟷, 𝟸, 𝟹, 𝟺] → игнорируем середину.

Что выведет код?
Anonymous voting

Оператор += для списков работает in-place (изменяет объект на месте), в отличие от обычной конкатенации +, которая создаёт новый список. Разбор по шагам: 🔘𝚊 = создаёт список. 🔘𝚋 = 𝚊 создаёт новую ссылку на тот же список; 𝚊 и 𝚋 указывают на один объект в памяти. 🔘𝚊 += вызывает метод 𝚊.𝚎𝚡𝚝𝚎𝚗𝚍() — расширяет существующий список, добавляя элемент 3. Объект не меняется, изменяется его содержимое. 🔘Поскольку 𝚋 указывает на тот же объект, изменения видны и через 𝚋. 🔘𝚊 == 𝚋 → True (значения равны), 𝚊 𝚒𝚜 𝚋 → True (это один и тот же объект). Сравнение с обычным + Если бы использовали 𝚊 = 𝚊 + [3], поведение было бы другим. Создавался бы новый список 𝚊. Переменная 𝚋 продолжала бы указывать на старый список , поэтому 𝚊 == 𝚋 → False, 𝚊 𝚒𝚜 𝚋 → False. Почему += работает in-place Для изменяемых типов (списки, множества, словари) оператор += оптимизирован: вместо создания нового объекта он модифицирует существующий. Для неизменяемых типов (строки, кортежи, числа) += всегда создаёт новый объект. Аналогично ведёт себя *=.

Что выведет код?
Anonymous voting