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

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

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

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

Другие наши проекты: https://tprg.ru/media
Download Telegram
Что выведет код?
Anonymous Quiz
25%
True True
20%
False False
48%
True False
6%
False True
🔥4👍3
Развёрнутое пояснение

🔘𝚃𝚛𝚞𝚎 — это объект типа 𝚋𝚘𝚘𝚕, а 𝚋𝚘𝚘𝚕 — подкласс 𝚒𝚗𝚝.

🔘𝚒𝚜𝚒𝚗𝚜𝚝𝚊𝚗𝚌𝚎(𝚃𝚛𝚞𝚎, 𝚒𝚗𝚝) проверяет: «является ли 𝚃𝚛𝚞𝚎 экземпляром 𝚒𝚗𝚝 или его подкласса?» — да, потому что 𝚋𝚘𝚘𝚕 наследуется от 𝚒𝚗𝚝. Результат: True.

🔘𝚝𝚢𝚙𝚎(𝚃𝚛𝚞𝚎) == 𝚒𝚗𝚝 проверяет: «является ли точный тип 𝚃𝚛𝚞𝚎 именно 𝚒𝚗𝚝?» — нет, точный тип это 𝚋𝚘𝚘𝚕. Результат: False.

Почему это важно
Для проверки типов почти всегда лучше использовать 𝚒𝚜𝚒𝚗𝚜𝚝𝚊𝚗𝚌𝚎, потому что она учитывает наследование. Проверка 𝚝𝚢𝚙𝚎(...) == нужна редко — только когда важен именно точный тип, без подклассов.
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥3
Что выведет код?
Anonymous Quiz
53%
10 parent
36%
10 затем Error
9%
Error
3%
parent 10
👍7
Развёрнутое пояснение

🔘При создании 𝙲𝚑𝚒𝚕𝚍() вызывается 𝙲𝚑𝚒𝚕𝚍.__𝚒𝚗𝚒𝚝__(), который устанавливает только 𝚜𝚎𝚕𝚏.𝚊𝚐𝚎 = 𝟷𝟶.

🔘Родительский 𝙿𝚊𝚛𝚎𝚗𝚝.__𝚒𝚗𝚒𝚝__() не вызывается автоматически — Python не делает этого за вас.

🔘Атрибут 𝚗𝚊𝚖𝚎 не существует у объекта 𝚌.

🔘𝚌.𝚊𝚐𝚎 возвращает 𝟷𝟶, но 𝚌.𝚗𝚊𝚖𝚎 выбрасывает AttributeError.

Почему это важно
В отличие от некоторых языков, Python не вызывает конструктор родителя автоматически. Если дочерний класс переопределяет __𝚒𝚗𝚒𝚝__, нужно явно вызвать 𝚜𝚞𝚙𝚎𝚛().__𝚒𝚗𝚒𝚝__(...), иначе инициализация родителя не произойдёт.
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍1
Развёрнутое пояснение

1️⃣Список 𝚊 содержит два вложенных списка: [𝟷, 𝟸] и [𝟹, 𝟺].

2️⃣Вызов 𝚊.𝚌𝚘𝚙𝚢() создаёт новый внешний список 𝚋, но элементы 𝚋[𝟶] и 𝚋[𝟷] — это те же самые объекты, что и 𝚊[𝟶] и 𝚊[𝟷], не их копии.

3️⃣Когда выполняется 𝚊[𝟶].𝚊𝚙𝚙𝚎𝚗𝚍(𝟻), изменяется вложенный список, на который указывают и 𝚊[𝟶], и 𝚋[𝟶].

4️⃣Поэтому при печати 𝚋 видим [[𝟷, 𝟸, 𝟻], [𝟹, 𝟺]].

Почему это важно
Для полного копирования вложенных структур нужен 𝚌𝚘𝚙𝚢.𝚍𝚎𝚎𝚙𝚌𝚘𝚙𝚢(). Поверхностная копия через 𝚕𝚒𝚜𝚝.𝚌𝚘𝚙𝚢(), 𝚕𝚒𝚜𝚝(...) или срез [:] — частый источник багов с «призрачными» изменениями в якобы независимых данных.
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Что выведет код?
Anonymous Quiz
13%
[1, 2, 3]
39%
[]
39%
Error
9%
None
👍2
Развёрнутое пояснение

1️⃣Список 𝚗𝚞𝚖𝚜 содержит 𝟹 элемента с индексами 𝟶, 𝟷, 𝟸.

2️⃣Индексация 𝚗𝚞𝚖𝚜[𝟷𝟶𝟶] требует конкретный элемент — если его нет, это ошибка.

3️⃣Срез 𝚗𝚞𝚖𝚜[𝟷𝟶𝟶:] означает «от индекса 𝟷𝟶𝟶 до конца». Начало среза (𝟷𝟶𝟶) превышает длину списка, поэтому диапазон пуст.

4️⃣Python не считает это ошибкой: срез «пустого диапазона» — это просто пустой список [].

Аналогично, 𝚗𝚞𝚖𝚜[𝟷:𝟷𝟶𝟶] вернёт [𝟸, 𝟹], а не ошибку.

Почему это важно
Это удобно для безопасной работы с данными неизвестной длины, но может маскировать логические ошибки: код молча вернёт пустой список вместо падения, и баг останется незамеченным.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Что выведет код?
Anonymous Quiz
16%
[5, 4, 3, 2]
24%
[5, 4, 3]
6%
[3, 4]
55%
[]
👏4
Развёрнутое пояснение

1️⃣𝚛𝚊𝚗𝚐𝚎(𝟻, 𝟸) создаёт последовательность от 𝟻 до 𝟸 (не включая) с шагом по умолчанию +𝟷.

2️⃣Чтобы дойти от 𝟻 до 𝟸, прибавляя 𝟷, нужно... идти в обратную сторону. Но шаг положительный!

3️⃣Python не угадывает намерения: раз 𝟻 уже больше 𝟸 при положительном шаге, последовательность пуста.

4️⃣Для обратного отсчёта нужно писать 𝚛𝚊𝚗𝚐𝚎(𝟻, 𝟸, -𝟷) → [𝟻, 𝟺, 𝟹].

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

Потенциальная ошибка — ожидать, что 𝚛𝚊𝚗𝚐𝚎 сам «поймёт» направление. Пустой результат не вызывает исключения, цикл просто не выполнится ни разу, и баг может долго оставаться незамеченным.
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2
Развёрнутое пояснение

1️⃣Оператор | для словарей появился в Python 3.9 и создаёт новый словарь из двух исходных.

2️⃣Сначала берутся все пары из 𝚍𝟷: "𝚊": 𝟷, "𝚋": 𝟸.

3️⃣Затем добавляются пары из 𝚍𝟸: "𝚋": 𝟹, "𝚌": 𝟺. Ключ "𝚋" уже есть — его значение перезаписывается значением из правого словаря.

4️⃣Итог: {"𝚊": 𝟷, "𝚋": 𝟹, "𝚌": 𝟺}.

5️⃣Если поменять порядок: 𝚍𝟸 | 𝚍𝟷, то "𝚋" будет равно 𝟸 (из 𝚍𝟷).

Почему это важно
Порядок операндов критичен при слиянии конфигов, настроек по умолчанию и пользовательских значений. Паттерн 𝚍𝚎𝚏𝚊𝚞𝚕𝚝𝚜 | 𝚞𝚜𝚎𝚛_𝚌𝚘𝚗𝚏𝚒𝚐 — правильный, потому что пользовательские значения должны перезаписывать дефолтные.
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍2
Развёрнутое пояснение

1️⃣Внутри блока 𝚎𝚡𝚌𝚎𝚙𝚝 создаются две переменные: 𝚎 (алиас исключения) и 𝚖𝚜𝚐 (обычная строка).

2️⃣По спецификации Python, 𝚎𝚡𝚌𝚎𝚙𝚝 ... 𝚊𝚜 𝚎 неявно выполняет 𝚍𝚎𝚕 𝚎 при выходе из блока. Это сделано потому, что объект исключения хранит ссылку на traceback, который ссылается на все локальные переменные фрейма — без удаления возникнет утечка памяти.

3️⃣Переменная 𝚖𝚜𝚐 — обычная строка, она не удаляется и доступна после блока.

4️⃣𝚙𝚛𝚒𝚗𝚝(𝚖𝚜𝚐) срабатывает, а вот второй, а 𝚙𝚛𝚒𝚗𝚝(e) при обращении к 𝚎 выбрасывает NameError.

Почему это важно
Если нужно сохранить исключение для использования после блока 𝚎𝚡𝚌𝚎𝚙𝚝, его нужно явно присвоить другой переменной (как 𝚖𝚜𝚐 в примере). Иначе код упадёт в неожиданном месте.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2