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
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
Что выведет код?
Anonymous Quiz
40%
10 10
46%
10 8
8%
8 8
6%
8 10
👍3
Развёрнутое пояснение

1️⃣𝚒𝚗𝚝("𝟶𝟷𝟶") вызывается без второго аргумента, значит основание — 𝟷𝟶. Строка "𝟶𝟷𝟶" парсится как десятичное число, ведущий ноль не имеет значения. Результат: 𝟷𝟶.

2️⃣Литерал 𝟶𝚘𝟷𝟶 в Python — это восьмеричная запись: 𝟷 × 𝟾 + 𝟶 = 𝟾.

3️⃣В Python 2 запись 𝟶𝟷𝟶 без буквы 𝚘 тоже была восьмеричной, что вызывало путаницу. В Python 3 это запретили: 𝟶𝟷𝟶 как литерал — это SyntaxError, нужно писать 𝟶𝚘𝟷𝟶.

4️⃣Но 𝚒𝚗𝚝("𝟶𝟷𝟶") — это парсинг строки, и тут ведущий ноль просто пропускается.

Почему это важно
При парсинге данных из файлов или API числа вроде "010" могут означать и десятичное 𝟷𝟶, и восьмеричное 𝟾 — зависит от контекста. Если нужен восьмеричный парсинг, пишите 𝚒𝚗𝚝("𝟶𝟷𝟶", 𝟾) явно.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
Что выведет код?
Anonymous Quiz
15%
1 2
7%
0 1
74%
1 1
4%
Error
👍2
Развёрнутое пояснение

1️⃣Начальные значения: 𝚊 = 𝟶, 𝚋 = 𝟷.

2️⃣Выражение 𝚊, 𝚋 = 𝚋, 𝚊 + 𝚋 сначала вычисляет правую часть как кортеж: (𝚋, 𝚊 + 𝚋) → (𝟷, 𝟶 + 𝟷) → (𝟷, 𝟷).

3️⃣Только после этого значения распаковываются: 𝚊 = 𝟷, 𝚋 = 𝟷.

4️⃣Можно ожидать, что 𝚋 = 𝟸, думая, что сначала 𝚊 станет 𝟷, а потом 𝚊 + 𝚋 = 𝟷 + 𝟷 = 𝟸. Но нет — правая часть вычисляется со старыми значениями.

Почему это важно
Это то, что делает 𝚊, 𝚋 = 𝚋, 𝚊 безопасным свопом без временной переменной. Но в более сложных выражениях, как здесь (числа Фибоначчи), легко неправильно предсказать результат, если не помнить это правило.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Что выведет код?
Anonymous Quiz
33%
True
18%
False
18%
check True
23%
check False
8%
Error
👍4
Развёрнутое пояснение

1️⃣Список [𝚃𝚛𝚞𝚎, 𝚙𝚛𝚒𝚗𝚝("𝚌𝚑𝚎𝚌𝚔", 𝚎𝚗𝚍=" "), 𝚃𝚛𝚞𝚎] вычисляется слева направо при создании.

2️⃣Вызов 𝚙𝚛𝚒𝚗𝚝("𝚌𝚑𝚎𝚌𝚔", 𝚎𝚗𝚍=" ") печатает check (с пробелом вместо переноса строки) и возвращает 𝙽𝚘𝚗𝚎 — все функции без явного 𝚛𝚎𝚝𝚞𝚛𝚗 возвращают 𝙽𝚘𝚗𝚎.

3️⃣Список превращается в [𝚃𝚛𝚞𝚎, 𝙽𝚘𝚗𝚎, 𝚃𝚛𝚞𝚎].

4️⃣Функция 𝚊𝚕𝚕() проверяет истинность всех элементов. Первый элемент 𝚃𝚛𝚞𝚎 — истинный, второй 𝙽𝚘𝚗𝚎 — ложный, поэтому 𝚊𝚕𝚕() сразу возвращает False.

5️⃣Переменная 𝚛𝚎𝚜𝚞𝚕𝚝 получает False, и печатается check (из 𝚙𝚛𝚒𝚗𝚝), а затем False.

Почему это важно
Встраивание функций с побочными эффектами в проверки 𝚊𝚕𝚕() или 𝚊𝚗𝚢() может давать неожиданный результат, если функция возвращает 𝙽𝚘𝚗𝚎 или другое falsy-значение.
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Что выведет код?
Anonymous Quiz
43%
True
21%
False
3%
None
33%
Error
👍1👀1