Python: Чанкование потока

Python: Списки 8 сообщений
Обновлено: 29 марта, 11:36
197
Студентов
70%
Завершения

В испытании "Чанкование" вам нужно было реализовать функцию, которая "нарезает" входную последовательность (любой iterable) на куски заданной длины. В этом же испытании вам нужно будет проделать нечто подобное, но уже с итератором — потенциально бесконечным! Иначе говоря, вам предстоит обрабатывать поток данных. Примерами таких потоков могут быть читаемый с диска файл очень большого размера или данные видео-трансляции, передаваемые по сети. В обоих случаях вы не можете себе позволить получить все данные сразу в виде структуры в памяти — вам её просто не хватит. И поэтому же вы не можете накапливать список кусочков внутри вашей функции, вам нужно возвращать поток кусочков.

src/solution.py

Реализуйте функцию ichunks(), которая должна принимать в качестве аргументов размер кусочка (положительное целое число) и источник данных (итератор). Вернуть функция должна итератор списков заданной длины, содержащих элементы из источника данных.

Внимание, в этот раз вам нужно будет формировать куски строго заданной длины! Если для последнего куска (если поток вообще закончится) не хватит элементов, то весь кусок отбрасывается!

Примеры применения функции:

list(ichunks(2, [1, 2, 3, 4, 5]))
# [[1, 2], [3, 4]]
# ^ пятёрка была отброшена

import itertools
# itertools.count() - бесконечный поток чисел 1, 2, 3...
list(itertools.islice(itertools.count(), 10000, 10005))
# [10000, 10001, 10002, 10003, 10004]

stream = ichunks(3, itertools.count())  # поток троек чисел
list(itertools.islice(stream, 10000, 10002))
# [[30000, 30001, 30002], [30003, 30004, 30005]]

Возможно, вы отметили, что имя функции начинается с "i" и отрезает то, что будет содержать возвращаемый итератор. Такое имя выбрано неспроста: похожим образом нередко именуют функции, работающие с итераторами. Например, несколько функций из стандартного модуля itertools названы в этом стиле.

У нас, увы, нет возможности проверить код на переполнение памяти. Поэтому мы полагаемся на вашу ответственность. Если вы вернёте что-то вроде iter(huge_list), тесты будут пройдены, но такое решение не будет по-настоящему правильным!

Подсказки

  • Чтобы вернуть итератор, воспользуйтесь при решении функциями, которые уже возвращают итераторы: map, zip, функции из модуля itertools.

Для полного доступа к испытанию нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Впечатления

Аватар пользователя Руслан Беляутдинов
Руслан Беляутдинов 01 июля 2020

Приветствую. Полнейший ступор. Прошу какого-нибудь толчка в нужном направлении. Пока что была только идея создать итератор от входного параметра: stream = iter(source) потом делать каждый раз elem = next(stream) и уже что-то делать с этим элементом (проверять на размерность и добавлять к чанку, а потом уже как-то добавлять чанк к выводимому результату. Но возникает проблема: я не знаю, когда в потоке возникнет StopIteration.

UPD: Ну, я, хоть и на чуток, сдвинулся с места. По крайней мере со списками на репле работает, подскажите направление движения, пожалуйста! https://ru.hexlet.io/code_reviews/285418?submission_id=361042