Question
How can I split a Python list of any length into smaller chunks of equal size?
For example, if I have a list with an arbitrary number of items, I want to divide it into sublists where each sublist contains n items. If the list length is not perfectly divisible by n, the final chunk may contain fewer items.
Related topics often include iterating over a list in chunks and applying similar chunking logic to strings.
Short Answer
By the end of this page, you will understand how list chunking works in Python, why slicing is the most common solution, how to handle uneven final chunks, and how this pattern is used in real programs such as batching API requests, pagination, and data processing.
Concept
In Python, chunking a list means breaking one list into smaller lists of a fixed size.
For example:
numbers = [1, 2, 3, 4, 5, 6, 7]
If the chunk size is 3, the result should be:
[[1, 2, 3], [4, 5, 6], [7]]
The last chunk contains the remaining items because the list length is not always a perfect multiple of the chunk size.
This matters because real programs often need to process data in batches instead of all at once. Common reasons include:
- sending API requests in groups
- paginating results
- processing large datasets safely
- reducing memory usage in some workflows
- grouping items for display in a user interface
The most common Python solution uses list slicing inside a loop or list comprehension. Slicing lets you take a portion of a list from one index to another.
A chunking solution usually follows this idea:
- start at index
0 - move forward by
chunk_sizeeach time - slice from the current index to
current index + chunk_size - stop when you reach the end of the list
This is simple, readable, and works well for beginners and production code.
Mental Model
Think of a list like a long loaf of bread.
- The full loaf is your original list.
- The knife cuts it every
nitems. - Each slice becomes one chunk.
- If the loaf does not divide evenly, the last piece is smaller.
So if your loaf has 10 items and you cut every 4 items, you get:
- first slice: 4 items
- second slice: 4 items
- last slice: 2 items
Python slicing is the knife that makes those cuts.
Syntax and Examples
The most common Python pattern is:
chunks = [my_list[i:i + size] for i in range(0, len(my_list), size)]
Example
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
size = 4
chunks = [numbers[i:i + size] for i in range(0, len(numbers), size)]
print(chunks)
Output:
[[1, 2, 3, 4], [5, 6, 7, 8], [9]]
How it works
range(0, len(numbers), size)generates starting indexes:0, 4, 8numbers[i:i + size]takes a slice from each starting index
Step by Step Execution
Consider this code:
items = [10, 20, 30, 40, 50, 60, 70]
size = 3
chunks = [items[i:i + size] for i in range(0, len(items), size)]
print(chunks)
Step 1: Calculate the range
range(0, len(items), size)
Since len(items) is 7 and size is 3, this becomes:
range(0, 7, 3)
This produces the indexes:
0, 3, 6
Step 2: Slice at each index
Real World Use Cases
Chunking lists appears in many practical tasks.
Batch API requests
Some APIs limit how many items you can send at once.
user_ids = [1, 2, 3, 4, 5, 6, 7]
for batch in [user_ids[i:i + 3] for i in range(0, len(user_ids), 3)]:
print("Send batch:", batch)
Pagination
A web app may display records 20 at a time.
products = list(range(1, 51))
pages = [products[i:i + 20] for i in range(0, len(products), 20)]
Processing files in groups
If you need to process thousands of filenames, chunking can make the work easier to manage.
files = [, , , ]
chunks = [files[i:i + ] i (, (files), )]
Real Codebase Usage
In real codebases, developers usually wrap chunking logic in a function so it can be reused and validated.
Common helper function
def chunk_list(items, size):
if size <= 0:
raise ValueError("size must be greater than 0")
return [items[i:i + size] for i in range(0, len(items), size)]
This adds a guard clause to reject invalid input early.
Validation pattern
Developers often validate arguments before processing:
def send_batches(items, batch_size):
if batch_size <= 0:
raise ValueError("batch_size must be positive")
for i in range(0, len(items), batch_size):
batch = items[i:i + batch_size]
print("Processing", batch)
Streaming vs building a full list
In some projects, developers prefer a generator when the input is large:
Common Mistakes
Using a chunk size of 0
Broken code:
items = [1, 2, 3]
size = 0
chunks = [items[i:i + size] for i in range(0, len(items), size)]
This raises an error because range() cannot use a step of 0.
Avoid it by validating the size:
if size <= 0:
raise ValueError("size must be greater than 0")
Forgetting that the last chunk may be smaller
Broken assumption:
items = [1, 2, 3, 4, 5]
size = 2
chunks = [items[i:i + size] for i in range(0, len(items), size)]
for chunk in chunks:
print(chunk[1])
Comparisons
| Approach | Result type | Best for | Notes |
|---|---|---|---|
| List slicing with list comprehension | List of lists | Simple chunking | Most common and readable |
for loop with slicing | List of lists | Beginners, debugging | Easier to trace step by step |
Generator with yield | Iterator of chunks | Large inputs | More memory-friendly |
| Manual item-by-item grouping | Custom | Special rules | More code, useful for unusual logic |
List comprehension vs loop
# List comprehension
chunks = [items[i:i + size] for i in (, (items), size)]
Cheat Sheet
Basic chunking
chunks = [items[i:i + size] for i in range(0, len(items), size)]
Reusable function
def chunk_list(items, size):
if size <= 0:
raise ValueError("size must be greater than 0")
return [items[i:i + size] for i in range(0, len(items), size)]
Generator version
def chunk_generator(items, size):
if size <= 0:
raise ValueError("size must be greater than 0")
for i in range(0, len(items), size):
yield items[i:i + size]
Key rules
sizemust be greater than
FAQ
How do I split a Python list into chunks of size n?
Use slicing with a step in range():
[items[i:i + n] for i in range(0, len(items), n)]
What happens if the list length is not divisible by the chunk size?
The final chunk will contain the remaining items and may be smaller than the others.
Can I chunk a list without using a list comprehension?
Yes. You can use a regular for loop and append each slice to a result list.
Why does Python slicing work even when the end index is too large?
Python slices stop safely at the end of the list instead of raising an error.
Should I use a generator instead of returning a list?
Use a generator when you want to process chunks one at a time or reduce memory usage for large inputs.
Can I use the same idea for strings?
Yes. Strings also support slicing, so the same pattern works, but the result will be chunks of strings instead of lists.
What error happens if the chunk size is 0?
You will get an error from range() because its step cannot be zero.
Mini Project
Description
Build a small batching utility for processing email recipients. In real applications, you often cannot send thousands of records in one operation, so you split the data into smaller groups. This project demonstrates list chunking, validation, and iteration over each batch.
Goal
Create a Python function that splits a list of email addresses into fixed-size batches and prints each batch for processing.
Requirements
- Create a function that accepts a list of email addresses and a batch size.
- Validate that the batch size is greater than 0.
- Return the email addresses as a list of chunks.
- Print each chunk with its batch number.
- Allow the final batch to contain fewer items if needed.
Keep learning
Related questions
@staticmethod vs @classmethod in Python Explained
Learn the difference between @staticmethod and @classmethod in Python with clear examples, use cases, mistakes, and a mini project.
Catch Multiple Exceptions in One except Block in Python
Learn how to catch multiple exceptions in one Python except block using tuples, with examples, mistakes, and real-world usage.
Convert Bytes to String in Python 3
Learn how to convert bytes to str in Python 3 using decode(), text mode, and proper encodings with practical examples.