π‘ Problem Formulation: When working with lists in Python, you might encounter situations where you want to convert a flat list into a list of sublists, each of a specified length. For example, given the input list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
and a step value of 3
, the desired output would be [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
. This article explores different methods to achieve this transformation.
Method 1: Using List Comprehension
This method utilizes list comprehension to create the list of lists. It is Pythonic and concise, making use of Python’s slicing capabilities. The step value is used as the slicer increment within a range determined by the length of the original list.
Here’s an example:
def chunk_list(lst, step): return [lst[i:i + step] for i in range(0, len(lst), step)] example_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(chunk_list(example_list, 3))
Output: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
The chunk_list
function takes a list and a step value. It generates a new list where each element is a sublist created by taking a slice of the original list from the current index i
to i + step
. This process is repeated until the list is completely sliced.
Method 2: Using the itertools.islice()
Method
The itertools.islice()
method is part of Python’s itertools module, which allows for efficient looping. This method can be used to slice the input list according to the step value without creating intermediate copies of the list. It is especially efficient for large lists.
Here’s an example:
from itertools import islice def chunk_list_iter(lst, step): return [list(islice(lst, i, None, step)) for i in range(step)] example_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(chunk_list_iter(example_list, 3))
Output: [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]]
The chunk_list_iter
function uses islice
to create sublists starting from each index within the step range. Each sublist takes every step
th element. Note that this approach differs from the previous one in how the sublists are constructed, which may or may not meet the user’s needs.
Method 3: Using a While Loop
This method involves a manual approach using a while loop, where you iteratively slice the list until all elements are included in the new list of lists. This is a more traditional, explicit way of handling list chunking.
Here’s an example:
def chunk_list_while(lst, step): chunks = [] i = 0 while i < len(lst): chunks.append(lst[i:i + step]) i += step return chunks example_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(chunk_list_while(example_list, 3))
Output: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
The chunk_list_while
function initializes an empty list to store the chunks. It then iterates over the original list, slicing it from the current index i
to i + step
and appending this sublist to the chunks list. The index i
is incremented by the step value each iteration until the end of the list is reached.
Method 4: Using Recursion
Recursion can be used to achieve the same result by continuously breaking down the list into a head, which is a sublist of the desired step length, and a tail, which is the remainder of the list. This pattern continues until the tail is empty.
Here’s an example:
def chunk_list_recursive(lst, step): if not lst: return [] return [lst[:step]] + chunk_list_recursive(lst[step:], step) example_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(chunk_list_recursive(example_list, 3))
Output: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
The chunk_list_recursive
function bases its operation on two cases. If the list is empty, it returns an empty list. Otherwise, it constructs a new list with the first step
elements as the head, and then recursively calls itself with the remainder of the list.
Bonus One-Liner Method 5: Using numpy.array_split()
For those who are not averse to using third-party libraries, NumPy offers the array_split()
method which can handle splitting arrays into sublists of varying sizes, which is useful when the list size isnβt divisible by the step value.
Here’s an example:
import numpy as np example_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] step = 3 chunks = np.array_split(example_list, np.ceil(len(example_list)/step).astype(int)) chunks = [list(chunk) for chunk in chunks] print(chunks)
Output: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
The numpy.array_split
function is passed the original list and the number of desired splits, rounded up to ensure all elements are included. Each chunk is then converted back into a list, resulting in a list of lists.
Summary/Discussion
- Method 1: List Comprehension. It is concise and Pythonic. However, list comprehensions may be less clear for beginners.
- Method 2:
itertools.islice()
. This is memory efficient and good for large lists, but the resulting chunks are different from traditional chunking. - Method 3: While Loop. This method is clear and explicit, but it can be verbose compared to list comprehensions.
- Method 4: Recursion. It’s elegant for small lists but can lead to a stack overflow error with very large lists.
- Method 5:
numpy.array_split()
. One-liner and can handle uneven splits gracefully, but relies on NumPy which is an extra dependency if not already in use.