Python: задачки и вопросы
7.4K subscribers
1.31K photos
1 video
1 file
122 links
Вопросы и задачки для подготовки к собеседованиям и прокачки навыков

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

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

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

Другие наши проекты: https://tprg.ru/media
Download Telegram
Развёрнутое пояснение

1️⃣Создаётся список 𝚗𝚞𝚖𝚜 = [𝟷, 𝟸, 𝟹], переменная 𝚊 получает ссылку на тот же самый объект: и 𝚊, и 𝚗𝚞𝚖𝚜 указывают на один список.

2️⃣Выражение 𝚗𝚞𝚖𝚜[:] = [𝟺, 𝟻] — это именно срезовое присваивание: левая часть берёт весь список как срез, а правая заменяет его содержимое элементами из нового списка.

3️⃣В результате исходный объект списка переписывается на [𝟺, 𝟻], но ссылка 𝚊 по‑прежнему указывает на него же, так что и 𝚊, и 𝚗𝚞𝚖𝚜 теперь содержат один и тот же список [𝟺, 𝟻].

4️⃣𝚙𝚛𝚒𝚗𝚝(𝚊, 𝚗𝚞𝚖𝚜) печатает [4, 5] [4, 5].

Почему это важно
Потом что [:] = — это не то же самое, что простое =, и любое незаметное срезовое присваивание может поменять список, который уже разделяют несколько переменных или даже разные части кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Весь год вы носили футболки и джинсы… Хватит!

Заглядывайте к нам в виртуальную примерочную и выбирайте себе идеальный скин для встречи Нового года!

Делитесь в комментариях, какой скин вам выпал 👀
🎉2
Развёрнутое пояснение

1️⃣При определении класса 𝙱𝚘𝚡 создаётся атрибут класса 𝚒𝚝𝚎𝚖𝚜 и привязывается к пустому списку []; этот список один на весь класс, а не на экземпляр.

2️⃣В конструкторе __init__ обращение 𝚜𝚎𝚕𝚏.𝚒𝚝𝚎𝚖𝚜 находит этот атрибут класса (у экземпляра ещё нет своего 𝚒𝚝𝚎𝚖𝚜) и вызывает у него метод 𝚊𝚙𝚙𝚎𝚗𝚍.

3️⃣Создание 𝚊 = 𝙱𝚘𝚡(𝟷) добавляет 𝟷 в общий список → теперь 𝚒𝚝𝚎𝚖𝚜 = [𝟷]. Создание 𝚋 = 𝙱𝚘𝚡(𝟸) добавляет 𝟸 в тот же самый список → [𝟷, 𝟸].

4️⃣И 𝚊.𝚒𝚝𝚎𝚖𝚜, и 𝚋.𝚒𝚝𝚎𝚖𝚜 ссылаются на один и тот же общий список, поэтому print(a.items, b.items) выводит [1, 2] [1, 2].

Почему это важно
Общий изменяемый атрибут класса легко превращается в неявный «shared state» между инстансами и рождает трудноуловимые баги; если список должен быть отдельным у каждого объекта, его нужно создавать в __init__ как 𝚜𝚎𝚕𝚏.𝚒𝚝𝚎𝚖𝚜 = [].
Please open Telegram to view this post
VIEW IN TELEGRAM
6
Что выведет код?
Anonymous Quiz
46%
[]
6%
[2, 4, 6, 8]
29%
[4, 8]
19%
Error
🤝61
Развёрнутое пояснение

🔘Список 𝚗𝚞𝚖𝚜 = [𝟸, 𝟺, 𝟼, 𝟾]. Цикл использует внутренний индекс, который увеличивается на каждой итерации.

0️⃣Шаг 𝟶: индекс 𝟶, элемент 𝟸, условие истинно, вызывается 𝚗𝚞𝚖𝚜.𝚛𝚎𝚖𝚘𝚟𝚎(𝟸). Список становится [𝟺, 𝟼, 𝟾], но индекс уже переходит к 𝟷.

1️⃣Шаг 𝟷: индекс 𝟷, в списке [𝟺, 𝟼, 𝟾] это элемент 𝟼 (а не 𝟺!), условие истинно, удаляем 𝟼. Список становится [𝟺, 𝟾], индекс переходит к 𝟸.

2️⃣Шаг 𝟸: индекс 𝟸 выходит за пределы списка длины 𝟸, цикл завершается.

3️⃣Элементы 𝟺 и 𝟾 никогда не были проверены, потому что итератор их «перепрыгнул». Результат: [𝟺, 𝟾].

Почему это важно
Задача наглядно показывает, почему нельзя удалять элементы из списка во время итерации по нему: даже если кажется, что «всё должно удалиться», половина элементов останется. Безопасные альтернативы: итерация по копии 𝚏𝚘𝚛 𝚡 𝚒𝚗 𝚗𝚞𝚖𝚜[:], list comprehension [𝚡 𝚏𝚘𝚛 𝚡 𝚒𝚗 𝚗𝚞𝚖𝚜 𝚒𝚏 𝚡 % 𝟸 != 𝟶], или проход в обратном порядке.
Please open Telegram to view this post
VIEW IN TELEGRAM
22
Развёрнутое пояснение

1️⃣В словаре 𝚍 два ключа: 𝟷 и 𝟸; соответствующие значения — "𝚘𝚗𝚎" и "𝚝𝚠𝚘".

2️⃣Выражение 𝟷 𝚒𝚗 𝚍 проверяет наличие 𝟷 среди ключей словаря; такой ключ есть, поэтому результат — True.

3️⃣Выражение "𝚘𝚗𝚎" 𝚒𝚗 𝚍 тоже смотрит только на ключи: строка "𝚘𝚗𝚎" не является ключом, это значение; поэтому результат — False.

4️⃣Функция 𝚙𝚛𝚒𝚗𝚝(𝟷 𝚒𝚗 𝚍, "𝚘𝚗𝚎" 𝚒𝚗 𝚍) выводит True False.

Почему это важно
Путаница между проверкой по ключам и по значениям часто ломает валидацию и условия: чтобы искать по значениям, нужно явно использовать "𝚘𝚗𝚎" 𝚒𝚗 𝚍.𝚟𝚊𝚕𝚞𝚎𝚜() или итерироваться по парам, а не надеяться на поведение по умолчанию.
Please open Telegram to view this post
VIEW IN TELEGRAM
Что выведет код?
Anonymous Quiz
36%
[3, 4, 5]
7%
[3, 4]
29%
[]
28%
Error
Развёрнутое пояснение

1️⃣Список 𝚊 = [𝟷, 𝟸, 𝟹, 𝟺, 𝟻]. Индекс −𝟹 соответствует элементу 𝟹 (третий с конца), а индекс 𝟶 — элементу 𝟷 (первый).

2️⃣Срез [𝚜𝚝𝚊𝚛𝚝:𝚜𝚝𝚘𝚙] идёт слева направо по умолчанию. Позиция −𝟹 (элемент 𝟹) находится правее позиции 𝟶 (элемент 𝟷).

3️⃣Поскольку 𝚜𝚝𝚊𝚛𝚝 > 𝚜𝚝𝚘𝚙 при движении слева направо, срез не захватывает ни одного элемента и возвращает [].

4️⃣Чтобы получить последние три элемента, нужно писать 𝚊[-𝟹:] (без указания конца) или 𝚊[-𝟹:𝙽𝚘𝚗𝚎].

Почему это важно
Ошибка [-𝚗:𝟶] вместо [-𝚗:] — частая ловушка при динамическом формировании срезов; результат всегда пуст, но ошибки не выбрасывается, и баг может долго оставаться незамеченным.
Please open Telegram to view this post
VIEW IN TELEGRAM
Канал по нейронкам, который часто пересекается с Python по темам: @neuro_channel

Веду его тоже я, так что если вам нравятся задачки здесь, то буду рад видеть вас и в «Нейроканале». Это всё часть медиа Tproger.

Три примечательных поста:

1️⃣Про утилиту, которая автоматически снимает цензуру (safety alignment) с трансформерных языковых моделей без дообучения и ручного тюнинга.

2️⃣Разбор сборки GPT‑OSS с нуля на чистом Python, без PyTorch и без GPU: последовательно с объяснениями от Softmax и RMSNorm до Grouped Query Attention.

3️⃣Обзор трендов Hugging Face за неделю с супер-кратким описанием моделей, выходит регулярно.

Плюс новости о выходе новых нейронок, чтобы не пропустить ничего важного. Все свежие громкие релизы, чтобы вы могли читать только один канал. Иногда получается даже раньше официального запуска, чем я особенно горжусь :)

Заходите и подписывайтесь:
@neuro_channel
Please open Telegram to view this post
VIEW IN TELEGRAM
1🙏1
Что выведет код?
Anonymous Quiz
62%
A
20%
B
12%
A B
7%
Error
Развёрнутое пояснение

1️⃣Вызов 𝚒𝚗𝚝("𝚊𝚋𝚌") выбрасывает 𝚅𝚊𝚕𝚞𝚎𝙴𝚛𝚛𝚘𝚛, потому что строка не является числом.

2️⃣Python идёт по 𝚎𝚡𝚌𝚎𝚙𝚝-блокам сверху вниз и проверяет, является ли выброшенное исключение экземпляром указанного класса.

3️⃣Первый блок ловит 𝙴𝚡𝚌𝚎𝚙𝚝𝚒𝚘𝚗; так как 𝚅𝚊𝚕𝚞𝚎𝙴𝚛𝚛𝚘𝚛 наследуется от 𝙴𝚡𝚌𝚎𝚙𝚝𝚒𝚘𝚗, условие выполняется, печатается A, и обработка завершается.

4️⃣Блок 𝚎𝚡𝚌𝚎𝚙𝚝 𝚅𝚊𝚕𝚞𝚎𝙴𝚛𝚛𝚘𝚛 становится «мёртвым кодом» — он никогда не выполнится.

Почему это важно
Правило: более специфичные исключения должны идти перед более общими. Иначе общий 𝚎𝚡𝚌𝚎𝚙𝚝 «съест» все ошибки, и специфичная обработка не сработает. В современном Python (3.11+) на это даже выдаётся SyntaxWarning. Да pyright подсветит, но в учебном примере я специально убрал подсветку.
Please open Telegram to view this post
VIEW IN TELEGRAM
1