Batch an Iterator into Fixed-Size Chunks
Group any iterable into fixed-size lists lazily, preserve the final partial batch, and stop cleanly when the source is exhausted.
Code
from collections.abc import Iterable, Iterator
from itertools import islice
from typing import TypeVar
T = TypeVar("T")
def chunked(items: Iterable[T], size: int) -> Iterator[list[T]]:
if size < 1:
raise ValueError("size must be at least 1")
iterator = iter(items)
while True:
batch = list(islice(iterator, size))
if not batch:
return
yield batch
def main() -> None:
for batch in chunked(range(1, 11), 3):
print(batch)
print(list(chunked([], 2)))
print(list(chunked((value for value in range(3)), 5)))
try:
list(chunked(range(5), 0))
except ValueError as error:
print("error:", error)
if __name__ == "__main__":
main()
Report a problem with this exampleOpens a pre-filled issue on GitHub.