How to chunk a list in Python 3?

Question:

I found the following code that is compatible with python2

from itertools import izip_longest
def grouper(n, iterable, padvalue=None):
  "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
  return izip_longest(*[iter(iterable)]*n, fillvalue=padvalue)

However, this isn’t working with Python 3. I get the following error

ImportError: cannot import name izip_longest

Can someone help?

I’d like to convert my list of [1,2,3,4,5,6,7,8,9] to [[1,2,3],[4,5,6],[7,8,9]]

Edit

Now Python3 compatible

Code below is adapted from the selected answer. Simply change name from izip_longest to zip_longest.

from itertools import zip_longest
def grouper(n, iterable, padvalue=None):
  "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
  return zip_longest(*[iter(iterable)]*n, fillvalue=padvalue)
Asked By: Mulan

||

Answers:

In Python 3’s itertools there is a function called zip_longest. It should do the same as izip_longest from Python 2.

Why the change in name? You might also notice that itertools.izip is now gone in Python 3 – that’s because in Python 3, the zip built-in function now returns an iterator, whereas in Python 2 it returns a list. Since there’s no need for the izip function, it also makes sense to rename the _longest variant for consistency.

Answered By: Ben James

According to the doc:

>>> s = [1,2,3,4,5,6,7,8,9]
>>> n = 3
>>> list(zip(*[iter(s)]*n))
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
Answered By: Julien Palard

After all that discussion above, here’s a python3 solution that I believe gives safer, more predicable results.

def chunker(iter, size):
    chunks = [];
    if size < 1:
        raise ValueError('Chunk size must be greater than 0.')
    for i in range(0, len(iter), size):
        chunks.append(iter[i:(i+size)])
    return chunks

example = [1,2,3,4,5,6,7,8,9]
print(' 1: ' + str(chunker(example, 1)))
print(' 3: ' + str(chunker(example, 3)))
print(' 4: ' + str(chunker(example, 4)))
print(' 8: ' + str(chunker(example, 8)))
print(' 9: ' + str(chunker(example, 9)))
print('10: ' + str(chunker(example, 10)))

The results are:

$ python3 iter_chunk.py 
 1: [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
 3: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
 4: [[1, 2, 3, 4], [5, 6, 7, 8], [9]]
 8: [[1, 2, 3, 4, 5, 6, 7, 8], [9]]
 9: [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
10: [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
Answered By: JasonGabler

The source code of the grouper() function included in the question is copied from the documentation for itertools, more specifically the section Itertools Recipes.

In this documentation, it is stated that:

This section shows recipes for creating an extended toolset using the existing itertools as building blocks.

Substantially all of these recipes and many, many others can be installed from the more-itertools project found on the Python Package Index:

pip install more-itertools

If you look at the documentation of the more-itertools package, then you will notice that the objective pursued in the question, i.e. to chunk a list, could be achieved with the following functions present in this package:

  • sliced() to yield a list from sliceable iterables,
  • chunked() to yield a list from non-sliceable iterables.
  • ichunked() to yield iterables instead of lists.

For many readers who would land on this page, as they are looking for a solution which fulfills this objective, this packages offers several advantages: i) code is always up-to-date, ii) many other useful functions are present.

Answered By: Wok
s = [1,2,3,4,5,6,7,8,9]
size = 4
chuck_list = [s[i:i+size] for i in range(0, len(s), size)]
Answered By: Jianjun Liu
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.