Python: задачки и вопросы
Развёрнутое пояснение:
1. Внутри report создаётся объект map, который при обходе вычисляет len для каждой строки.
2. sum(sizes) проходит по всем элементам: 3 + 4 + 2 = 9. После этого итератор исчерпан.
3. list(sizes) пытается снова обойти тот же объект map, но элементов больше нет, поэтому valid = 0.
4. Функция возвращает кортеж (9, 0), который и печатается.
Почему это важно: в пайплайнах обработки логов или событий часто передают map, filter или генераторное выражение сразу в несколько агрегирующих функций, ожидая, что каждая из них прочитает данные заново. Из-за одноразовости итераторов это приводит к заниженным счётчикам, потере записей и нестабильным отчётам, пока данные не материализовать в список.
2. sum(sizes) проходит по всем элементам: 3 + 4 + 2 = 9. После этого итератор исчерпан.
3. list(sizes) пытается снова обойти тот же объект map, но элементов больше нет, поэтому valid = 0.
4. Функция возвращает кортеж (9, 0), который и печатается.
Почему это важно: в пайплайнах обработки логов или событий часто передают map, filter или генераторное выражение сразу в несколько агрегирующих функций, ожидая, что каждая из них прочитает данные заново. Из-за одноразовости итераторов это приводит к заниженным счётчикам, потере записей и нестабильным отчётам, пока данные не материализовать в список.
✍3
Python: задачки и вопросы
Развёрнутое пояснение:
1. При определении функции log_event создаётся один пустой список buffer, который используется как значение по умолчанию.
2. Первый вызов log_event со строкой timeout добавляет эту строку в общий список и возвращает его, результат сохраняется в переменную a.
3. Второй вызов log_event со строкой 403 использует тот же список buffer, добавляет строку 403 и возвращает его, результат сохраняется в переменную b.
4. Переменные a и b указывают на один и тот же объект, поэтому print(a, b) выводит ['timeout', '403'] ['timeout', '403'].
Почему это важно: изменяемый аргумент по умолчанию часто встречается в функциях-логгерах, кэширующих обёртках и накопителях метрик, но на деле он работает как глобальное состояние между вызовами. В многопоточном коде это создаёт состояние гонки, а в тестах — нестабильные результаты. Правильный паттерн: buffer=None и создание нового списка внутри функции.
2. Первый вызов log_event со строкой timeout добавляет эту строку в общий список и возвращает его, результат сохраняется в переменную a.
3. Второй вызов log_event со строкой 403 использует тот же список buffer, добавляет строку 403 и возвращает его, результат сохраняется в переменную b.
4. Переменные a и b указывают на один и тот же объект, поэтому print(a, b) выводит ['timeout', '403'] ['timeout', '403'].
Почему это важно: изменяемый аргумент по умолчанию часто встречается в функциях-логгерах, кэширующих обёртках и накопителях метрик, но на деле он работает как глобальное состояние между вызовами. В многопоточном коде это создаёт состояние гонки, а в тестах — нестабильные результаты. Правильный паттерн: buffer=None и создание нового списка внутри функции.
✍1