Python: задачки и вопросы
Відкрити в Telegram
Вопросы и задачки для подготовки к собеседованиям и прокачки навыков Разместить рекламу: @tproger_sales_bot Правила общения: https://tprg.ru/rules Другие каналы: @tproger_channels Другие наши проекты: https://tprg.ru/media
Показати більше6 962
Підписники
-124 години
-67 днів
-5630 день
Архів дописів
Развёрнутое пояснение
1️⃣Вызов 𝚜𝚞𝚖(𝚒𝚝𝚎𝚛𝚊𝚋𝚕𝚎, 𝚜𝚝𝚊𝚛𝚝) эквивалентен последовательному сложению: 𝚜𝚝𝚊𝚛𝚝 + 𝚒𝚝𝚎𝚖𝟷 + 𝚒𝚝𝚎𝚖𝟸 + ....
2️⃣Здесь 𝚜𝚝𝚊𝚛𝚝 = [] (пустой список), а элементы итерируемого — [𝟷, 𝟸] и [𝟹, 𝟺].
3️⃣Первый шаг: [] + [𝟷, 𝟸] → [𝟷, 𝟸].
4️⃣Второй шаг: [𝟷, 𝟸] + [𝟹, 𝟺] → [𝟷, 𝟸, 𝟹, 𝟺].
5️⃣Переменная 𝚛𝚎𝚜𝚞𝚕𝚝 получает этот список, и print выводит [1, 2, 3, 4].
Почему это важно
Это «хакерский» способ сгладить список списков, но он неэффективен (квадратичная сложность из-за создания промежуточных списков); для реальных задач лучше использовать 𝚒𝚝𝚎𝚛𝚝𝚘𝚘𝚕𝚜.𝚌𝚑𝚊𝚒𝚗.𝚏𝚛𝚘𝚖_𝚒𝚝𝚎𝚛𝚊𝚋𝚕𝚎() или list comprehension.
Разбор по шагам
1️⃣Переменная 𝚡 имеет значение False.
2️⃣В условии 𝚢 := 𝚡 𝚘𝚛 𝚃𝚛𝚞𝚎 сначала вычисляется правая часть: 𝚡 𝚘𝚛 𝚃𝚛𝚞𝚎 → False or True → True.
3️⃣Затем walrus-оператор присваивает это значение переменной 𝚢, то есть 𝚢 = 𝚃𝚛𝚞𝚎.
4️⃣Условие if истинно (𝚢 равно True), поэтому выполняется print(y) и на экран выводится True.
Почему это важно
Если бы разработчик хотел присвоить 𝚢 значение 𝚡, а потом проверить 𝚢 𝚘𝚛 𝚃𝚛𝚞𝚎, нужны скобки: (𝚢 := 𝚡) 𝚘𝚛 𝚃𝚛𝚞𝚎. Без понимания приоритета легко получить неожиданный результат.
Развёрнутое пояснение
1️⃣Строка 𝚜 содержит: пробел, 𝚊, пробел, 𝚋, пробел — всего 5 символов.
2️⃣Метод 𝚜.𝚜𝚙𝚕𝚒𝚝() воспринимает любую последовательность пробелов как один разделитель и игнорирует ведущие/завершающие, поэтому результат — ['𝚊', '𝚋'], длина 𝟸.
3️⃣Метод 𝚜.𝚜𝚙𝚕𝚒𝚝(' ') разбивает ровно по каждому пробелу: пробел в начале даёт '', затем '𝚊', затем '𝚋', пробел в конце даёт ''; итого ['', '𝚊', '𝚋', ''] — длина 𝟺.
Почему это важно
Многие разработчики интуитивно считают, что 𝚜𝚙𝚕𝚒𝚝(' ') и 𝚜𝚙𝚕𝚒𝚝() — это одно и то же, но на практике разница критична при парсинге данных: логи, CSV-файлы или пользовательский ввод часто содержат лишние пробелы в начале/конце строк или двойные пробелы между словами. Если использовать 𝚜𝚙𝚕𝚒𝚝(' ') для такой строки, в результате появятся пустые элементы '', которые могут сломать дальнейшую обработку — например, 𝚒𝚗𝚝('') выбросит ошибку, а 𝚕𝚎𝚗(𝚛𝚎𝚜𝚞𝚕𝚝) покажет неверное количество «слов». Правило простое: если нужно разбить текст на слова — используй 𝚜𝚙𝚕𝚒𝚝() без аргументов; если нужно точное разбиение по конкретному символу с сохранением структуры — тогда 𝚜𝚙𝚕𝚒𝚝(' ').
Развёрнутое пояснение
1️⃣Вызов 𝚍𝚒𝚌𝚝.𝚏𝚛𝚘𝚖𝚔𝚎𝚢𝚜(['𝚊', '𝚋', '𝚌'], []) создаёт словарь с тремя ключами, но второй аргумент (пустой список) вычисляется один раз, и все три значения указывают на этот единственный список.
2️⃣Когда выполняется 𝚍['𝚊'].𝚊𝚙𝚙𝚎𝚗𝚍(𝟷), элемент 𝟷 добавляется в тот самый общий список.
3️⃣Поскольку 𝚍['𝚋'] и 𝚍['𝚌'] ссылаются на тот же объект, при печати видно {'a': [1], 'b': [1], 'c': [1]}.
Почему это важно
Это классическая ловушка при инициализации словарей со значениями-списками; правильный способ — использовать dict comprehension: {𝚔: [] 𝚏𝚘𝚛 𝚔 𝚒𝚗 𝚔𝚎𝚢𝚜} или 𝚍𝚎𝚏𝚊𝚞𝚕𝚝𝚍𝚒𝚌𝚝(𝚕𝚒𝚜𝚝).
Развёрнутое пояснение
🔘Функция 𝚊𝚕𝚕(𝚒𝚝𝚎𝚛𝚊𝚋𝚕𝚎) проверяет, все ли элементы истинны; внутри она перебирает элементы и возвращает False, как только встречает ложный; если цикл завершился без такого элемента — возвращает True.
🔘Для пустого списка цикл не выполняется ни разу, поэтому сразу возвращается True — переменная 𝚊 получает значение True.
🔘Функция 𝚊𝚗𝚢(𝚒𝚝𝚎𝚛𝚊𝚋𝚕𝚎) работает наоборот: возвращает True, как только встречает истинный элемент; если таких нет — возвращает False.
🔘Для пустого списка нет ни одного истинного элемента, поэтому 𝚋 получает False, и print(a, b) выводит True False.
Почему это важно
Это поведение часто ломает логику валидации: проверка 𝚊𝚕𝚕(𝚌𝚘𝚗𝚍𝚒𝚝𝚒𝚘𝚗𝚜) пройдёт, даже если список условий пуст, что может быть не тем, что ожидалось.
Repost from Типичный программист
Летим зимовать ✈️
Когда холодает, айтишники пакуют чемоданы, а мы разыгрываем ваучер на 50 000 рублей в Островке.
Поехать к морю или остаться среди снежных пейзажей — выбирайте сами!
Чтобы участвовать, нужно оставить любую реакцию под этим постом и подписаться на каналы ниже:
😎 Типичный программист
🐸 Библиотека программиста
🟢 Ostrovok! Tech
Теперь осталось нажать на кнопку участия под этим постом и вы в игре!
Итоги подведём 12 декабря. Победителя выберем с помощью бота. Подробнее с правилами можно ознакомиться здесь.
Всем удачи!
Участников: 27
Призовых мест: 1
Дата розыгрыша: 19:00, 12.12.2025 MSK (4 дня)
Встроенная функция 𝚛𝚘𝚞𝚗𝚍() в Python 3 округляет до ближайшего чётного числа. В английском это называют «banker's rounding» т.е. банковское округление.
Развёрнутое пояснение
1️⃣Значение 𝟶.𝟻 находится ровно посередине между 𝟶 и 𝟷; ближайшее чётное — 𝟶, поэтому 𝚊 получает 𝟶.
2️⃣Значение 𝟷.𝟻 находится посередине между 𝟷 и 𝟸; ближайшее чётное — 𝟸, поэтому 𝚋 получает 𝟸.
3️⃣Значение 𝟸.𝟻 находится посередине между 𝟸 и 𝟹; ближайшее чётное — 𝟸, поэтому 𝚌 тоже получает 𝟸.
4️⃣Функция print(a, b, c) выводит 0 2 2.
Почему это важно
Многие ожидают «школьного» округления (0.5 → 1), но Python 3 намеренно использует банковское, чтобы минимизировать накопление ошибки при суммировании большого количества округлённых значений. Если нужно классическое округление, придётся писать свою функцию или использовать модуль 𝚍𝚎𝚌𝚒𝚖𝚊𝚕.
А почему ошибка меньше накапливается то?
Я тоже не сразу понял, вот объяснение.
При обычном округлении цифра 5 всегда округляется вверх, и из-за этого возникает перекос — из 10 возможных дробных частей (0,0–0,9) пять округляются вверх (5, 6, 7, 8, 9) и только четыре вниз (1, 2, 3, 4), а ноль не меняется. Когда суммируются тысячи таких округлённых значений, этот небольшой сдвиг накапливается.
Банковское округление решает проблему тем, что числа с дробной частью ровно 0,5 округляются то вверх, то вниз — в зависимости от чётности целой части. Поскольку чётные и нечётные числа встречаются примерно одинаково часто, округления вверх и вниз статистически компенсируют друг друга.
На практике разница существенная: в примере с 1000 числами обычное округление даёт погрешность ~0,1%, а банковское ~0,01% для равномерного набора данных. Подробнее можно почитать в этой статье, например.
