Explain Codes LogoExplain Codes Logo

Split a Python list into other sublists i.e smaller lists

python
list-comprehension
memory-management
generators
Alex KataevbyAlex Kataev·Mar 6, 2025
TLDR

To break down lists into manageable chunks or sublists, list comprehension and slicing go hand in hand. Here's the syntax: sublists = [lst[i:i + n] for i in range(0, len(lst), n)]. Simply replace lst with your list, and n with the preferred sublist length.

Here’s a practical example of how you can split a list into sublists of size 2:

# Original list - let's call it the Superbowl of numbers lst = [1, 2, 3, 4, 5] # The new challenge: create a team of sublists sublists = [lst[i:i + 2] for i in range(0, len(lst), 2)] # Output: [[1, 2], [3, 4], [5]] # Challenge successful! We now have a team of sublists.

Smaller sublists for Python 2.x

Are you still a loyal Python 2.x user? Switch out range() with xrange() in the list comprehension for better memory management, as it generates numbers only when needed:

# Remember those old schoolhouse memories? This list does. lst = [1, 2, ..., 500] # Let's divide those memories into manageable boxes. sublists = [lst[i:i + 100] for i in xrange(0, len(lst), 100)] # Now, aren't they easier to walk through?

Dealing with the leftovers (the uneven sublist story)

Let's break some bread together! Whenever the list’s length is not a multiple of the defined sublist size, the balance is automatically packed into the last sublist:

# The party list - Going big or going home! lst = [1, 2, ..., 450] # The mission: divide the party crowd into smaller fun groups sublists = [lst[i:i + 100] for i in range(0, len(lst), 450)] # The crowd control strategy worked wonders. Last group: [451, ..., 500]

Equal-sized chunks using the power of itertools

The utility of the itertools.grouper pattern is unparalleled when it comes to evenly slicing lists. With a little tweak, it can also accommodate the final chunk:

from itertools import zip_longest # The 'grouper' - the party planner for the iterable crowd. def grouper(iterable, n, fillvalue=None): args = [iter(iterable)] * n return zip_longest(*args, fillvalue=fillvalue) # The crowd is here! lst = [1, 2, ..., 500] # Time to place them into different groups. sublists = list(grouper(lst, 100, fillvalue=None)) # Result: Groups of 100, with the last one being the 'I just got here' club.

Performance tweaks for the impatient coder

The memory saver: Generators

Dealing with large lists can feel like a wrestling match. Beat it by a generator expression, which procures sublists on-demand, enhancing efficiency of space:

# The big leaguer lst = [1, 2, ..., 10000] # Defeating the size with a handy generator sublists = (lst[i:i + 100] for i in range(0, len(lst), 100)) # Now, take a breather. Your memory thanked you!

The speed demon: Numpy

Performance is key for handling gargantuan lists. Employ numpy arrays to slice and dice rapidly:

import numpy as np # The colossal list lst = np.array([1, 2, ..., 10000]) # Armed with numpy, just watch how quickly we divide and conquer sublists = [lst[i:i + 100] for i in range(0, len(lst), 100)]

Essential precautions

Checking the sublist size

Dirty data is no one’s friend. Ensure the sublist size n is positive to keep unwanted surprise visits away:

# Just like a diligent security guard, verify before you let it through def validate_sublist_size(n): if n <= 0: raise ValueError("Sublist size must be a positive integer")

Handling the leftover sublist sizes

Balance is the essence when it comes to slicing lists. If sublist sizes do not divide the list evenly, we need to assess whether empty sublists should be averted or kept intact:

# The oddball party list lst = [1, 2, ..., 402] # Divide the crowd and accomodate the extras sublists = [lst[i:i + 100] for i in range(0, len(lst), 100)] # Kick out the party poopers sublists = [sublist for sublist in sublists if sublist]