Python: задачки и вопросы
6.89K subscribers
1.35K photos
1 video
1 file
128 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
Python: задачки и вопросы
Развёрнутое пояснение:

1. Вызов orders() создаёт объект генератора, но его тело пока не выполняется.

2. next(stream) запускает генератор: печатается open, затем выполнение доходит до yield 101 и приостанавливается.

3. Внешний print получает значение 101 и печатает его.

4. Следующий print выводит done, поскольку генератор всё ещё приостановлен на yield.

5. stream.close() передаёт в точку приостановки служебное исключение GeneratorExit. Обычное продолжение после yield не происходит, поэтому строка next не печатается.

6. Перед завершением генератор обязательно выполняет блок finally, который печатает close. Итоговый порядок строк: open, 101, done, close.

Почему это важно

Задача проверяет жизненный цикл генераторов и гарантированную очистку ресурсов. В потоковой обработке генератор может удерживать файл, соединение или транзакцию; если потребитель прекращает чтение досрочно, явный вызов close() запускает очистку из finally, но не продолжает обычную обработку оставшихся элементов.
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Разбор задачи

1️⃣Строковая переменная name содержит значение report.txt.

2️⃣Метод strip принимает множество символов: переданный аргумент .txt воспринимается как набор из точки, t и x.

3️⃣Интерпретатор удаляет символы из этого набора с обоих концов строки, пока не встретит первый символ, отсутствующий в наборе.

4️⃣Слева буква r не входит в набор, а справа удаляются расширение .txt и последняя буква t из слова report, после чего процесс останавливается на букве r.

5️⃣На экран выводится строка repor.

Почему это важно
Чтобы отрезать расширение, используйте name.removesuffix(".txt") (есть с Python 3.9) или pathlib.Path(name).stem. strip, lstrip и rstrip для этого не годятся: они портят имя каждый раз, когда его крайние буквы совпадают с символами расширения.
Please open Telegram to view this post
VIEW IN TELEGRAM
✍2
Please open Telegram to view this post
VIEW IN TELEGRAM
По шагам:

1️⃣Строка s состоит из шести кириллических букв.

2️⃣Первый вызов len(s) считает количество символов Юникода в строке, поэтому возвращает значение 6.

3️⃣Метод encode без параметров кодирует строку в байты по стандарту UTF-8, в котором каждый символ кириллицы занимает по два байта.

4️⃣Второй вызов len(s.encode()) определяет размер полученного объекта bytes, что даёт 12 байт.

5️⃣В итоге на экран выводится 6 12.

Почему это важно
Заголовок HTTP Content-Length и многие лимиты протоколов считают байты, а не символы. Если проверять такой лимит через len(s), русский текст окажется вдвое длиннее разрешённого. А если обрезать байты посреди буквы, например "привет".encode()[:3].decode(), будет UnicodeDecodeError. Для байтовых лимитов длину считают через len(s.encode()).
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
Разбор по шагам

1️⃣В определении списка после строки go пропущена запятая.

2️⃣Python склеивает строковые литералы, стоящие рядом, ещё при компиляции. Внутри скобок это работает, даже если они на разных строках.

3️⃣Строки go и rust склеиваются в один элемент gorust, а завершающая висячая запятая после него допустима и ни на что не влияет.

4️⃣В результате список langs содержит два элемента: python и gorust, а выражение langs[-1] извлекает последний из них.

5️⃣Команда print выводит на экран 2 gorust.

Почему это важно
Такая опечатка не вызывает ошибок и молча портит данные: в списке разрешённых хостов, колонок или аргументов командной строки одна запись склеивается с соседней. При этом саму склейку литералов в скобках часто применяют намеренно для аккуратного переноса длинных строк в коде.
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
Развёрнутое пояснение

1️⃣Создаётся словарь prices с единственной парой ключ-значение tea: 100.

2️⃣Вызов prices.keys() возвращает специальный объект представления dict_keys, который динамически связан со словарём и отражает его текущее состояние.

3️⃣При добавлении нового ключа coffee со значением 200 представление сразу видит изменения в живом словаре.

4️⃣list(names) превращает представление в список в момент вызова, а вызывается он уже после добавления coffee, когда в словаре два ключа. Порядок ключей — порядок вставки, он гарантирован с Python 3.7.

5️⃣На экран выводится итоговый список ['tea', 'coffee'].

Почему это важно
Если нужен снимок ключей на текущий момент, сохраняйте его сразу: list(prices). А добавлять или удалять ключи прямо во время обхода for k in prices.keys() нельзя: Python выбросит RuntimeError: dictionary changed size during iteration.
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
Подробное объяснение

1️⃣Функция sorted выполняет посимвольное сравнение строк по кодам символов без учёта числовых значений внутри текста.

2️⃣Первые три символа img у всех элементов совпадают, а на четвёртой позиции символ 1 у строк img10.png и img100.png меньше символа 9 у img9.png, поэтому img9.png сразу отправляется в конец.

3️⃣Между собой img10.png и img100.png совпадают в первых пяти символах, а на шестой позиции точка с кодом 46 оказывается меньше нуля с кодом 48.

4️⃣В результате первым идёт img10.png, вторым становится img100.png, а последним остаётся img9.png.

5️⃣Итоговый вывод на экран: ['img10.png', 'img100.png', 'img9.png'].

Почему это важно
Стандартная сортировка нарушает ожидаемый числовой порядок при обработке файлов, логов или кадров с номерами без ведущих нулей. Для «естественного» порядка число достают ключом сортировки: sorted(files, key=lambda f: int("".join(c for c in f if c.isdigit()))) вернёт ['img9.png', 'img10.png', 'img100.png'].
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Шаблон и условие — по очереди

1️⃣Изначально status содержит строку old. Конструкция match получает для проверки строку queued.

2️⃣В записи case status имя status является захватывающим шаблоном. Оно не сравнивается с прежним значением old: шаблон успешно связывает status со строкой queued.

3️⃣Только после этого проверяется условие status == "done". Оно ложно, поэтому тело первой ветки не выбирается. Следующий case _ подходит и печатает fallback.

4️⃣Ложное условие не отменяет уже выполненное связывание имени. После match переменная status содержит queued, и последний print выводит её. Результат: fallback, затем queued.

Почему это важно
Если использовать в шаблоне имя существующей переменной, её значение можно заменить ещё до проверки дополнительного условия. Для сравнения с конкретной строкой пишите строковый литерал, например case "done". Для захваченного значения удобно выбрать отдельное имя, чтобы не потерять прежний статус.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Разбор по шагам

1️⃣Список services содержит три строки: "api/v2", "db" и "auth".

2️⃣Выражение "api" in services проверяет, есть ли в списке элемент, равный строке "api".

3️⃣Строка "api/v2" начинается с "api", но целиком ей не равна. Строки "db" и "auth" тоже не совпадают с искомым значением.

4️⃣Подходящего элемента нет, поэтому результат проверки — False. Именно его выводит print.

Почему это важно
В списке разрешённых сервисов или имён файлов in ищет совпадение с целым элементом. Если нужна проверка начала имени сервиса, это условие задают явно: any(s.startswith("api/") for s in services) найдёт в этом списке "api/v2".
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Типичный программист
🧑‍💻 Какие навыки помогают вам в разработке в 2026 году?

Что вы чаще используете в работе? В каких задачах помогает ИИ, а где проще справиться самостоятельно?

Мы решили собрать портрет современного разработчика — и приглашаем вас поделиться своим опытом. Расскажите, какие навыки вам пригодились и как вы используете ИИ. Если обходите его стороной, нам тоже интересно узнать почему.

Опрос анонимный и займёт около 5 минут. Результаты опубликуем в общем большом исследовании.

👉 Пройти опрос
Please open Telegram to view this post
VIEW IN TELEGRAM
Разберём два выражения

1️⃣Объект p принадлежит классу Price. Метод __repr__ возвращает строку DEBUG, а __format__ — PUBLIC.

2️⃣В выражении f"{p}" Python вызывает p.__format__(""). Пустая строка означает, что после двоеточия не задан формат. Наш метод возвращает PUBLIC.

3️⃣В выражении f"{p!r}" сначала вызывается repr(p). Получается строка DEBUG, после чего форматирование применяется уже к этой строке. Метод Price.__format__ здесь не вызывается.

4️⃣Оба результата передаются в print, который разделяет их пробелом. Итоговый вывод: PUBLIC DEBUG.

Почему это важно
Класс может по-разному представлять объект в отчёте и при отладке. Например, __format__ выводит цену с валютой, а __repr__ показывает данные для диагностики. Добавление !r меняет путь преобразования, поэтому его нельзя считать просто декоративной пометкой.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM