Itertools на Python: разбейте поток на партии с лимитом
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Itertools в Python: задачи на комбинации, groupby и ленивые потоки.
Партии почтового терминала
На сортировочном терминале непрерывный поток посылок нарезается на партии фиксированного размера для автоматического сканера. Терминал отсчитывает полные пачки до тех пор, пока не наберётся заданный лимит таких партий либо пока во входном потоке не закончатся посылки.
Если установленный лимит полных партий достигнут, конвейер останавливается немедленно. Система не считывает из источника следующие элементы, а отдельный буфер ручной сортировки остаётся пустым. Если же поток исчерпался сам собой до выполнения лимита и в конце осталась незавершённая пачка, она не должна потеряться — эти посылки отправляются в буфер ручной сортировки как хвостовой остаток.
Реализуйте функцию, которая разделяет входной поток на генератор полных партий и извлечённый неполный остаток ручной сортировки, не допуская лишнего чтения данных при наборе лимита.
Что уже дано
В редакторе представлена заготовка функции postal_batches(source, batch_size, limit_batches). Вспомогательные функции make_postal_source и observe_postal_source уже доступны в среде исполнения для отладки и запуска проверочного примера, реализовывать их заново не требуется.
Что нужно сделать
Реализуйте функцию postal_batches(source, batch_size, limit_batches).
Функция принимает три аргумента:
source— одноразовый итератор строк (идентификаторов посылок длиной от 0 до 30 символов; общее количество элементов в источнике от 0 до 512);batch_size— положительное целое число, размер полной партии (от 1 до 64);limit_batches— неотрицательное целое число, максимальное количество выдаваемых полных партий (от 0 до 32).
Функция должна возвращать кортеж вида (batches, tail):
batches— одноразовый ленивый итератор, выдающий только полные партии в виде кортежей длиныbatch_size;tail— изначально пустой изменяемый список (list), куда помещается хвостовой остаток.
Правила обработки потока:
- В момент самого вызова
postal_batchesизsourceне должно считываться ни одного элемента. Все чтения происходят строго лениво по мере запросов из итератораbatches. - Каждый шаг получения очередной партии извлекает из
sourceне более одного набора элементов, сохраняя исходный порядок следования и возможные дубликаты идентификаторов. - Итератор
batchesвыдаёт не болееlimit_batchesполных партий. Как только это количество выдано, обращения кsourceполностью прекращаются: нельзя делать даже проверочный вызов для проверки конца потока. - Если лимит
limit_batchesравен 0, функция не считывает из источника ни одного значения, итераторbatchesзавершается сразу, аtailостаётся пустым. - Если поток естественным образом исчерпался (
StopIteration) до набора лимитаlimit_batchesи последняя сформированная пачка оказалась неполной (её размер больше 0, но меньшеbatch_size), эти элементы добавляются в списокtailпо месту (tail.extend(...)), а сам генераторbatchesзавершает работу и не выдаёт эту неполную пачку. - Если лимит партий достигнут либо поток исчерпался точно на границе полной партии (неполного остатка нет), список
tailостаётся пустым. - Список
tailзаполняется только в процессе обходаbatches; предварительно извлекать остаток при создании кортежа запрещено.
Ввод и вывод
Стандартные потоки stdin и stdout не используются. Проверяющая система импортирует и вызывает функцию верхнего уровня postal_batches напрямую из пространства имён модуля после выполнения кода студента.
Пример использования
source = make_postal_source(['a', 'b', 'c', 'd', 'e'])
batches, tail = postal_batches(source, 2, 3)
print(list(batches))
print(tail)
print(observe_postal_source(source)['successful_reads'])
Вывод:
[('a', 'b'), ('c', 'd')]
['e']
5
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- Как groupby группирует несортированные данные: тест itertools Python
- Itertools на Python: ленивый перебор комбинаций параметров
- Itertools на Python: объедините генераторы в непрерывный поток
- Groupby на Python: сводка последовательных серий событий
- Скользящие окна Python: генерация кортежей без загрузки всего потока
- Итераторы Python: сборка кадра из двух потоков без лишнего чтения
