Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative way to split a list into groups of n [duplicate]

Tags:

python

Let's say I have a list of arbitrary length, L:

L = list(range(1000)) 

What is the best way to split that list into groups of n? This is the best structure that I have been able to come up with, and for some reason it does not feel like it is the best way of accomplishing the task:

n = 25 for i in range(0, len(L), n):     chunk = L[i:i+25] 

Is there a built-in to do this I'm missing?

Edit: Early answers are reworking my for loop into a listcomp, which is not the idea; you're basically giving me my exact answer back in a different form. I'm seeing if there's an alternate means to accomplish this, like a hypothetical .split on lists or something. I also do use this as a generator in some code that I wrote last night:

def split_list(L, n):     assert type(L) is list, "L is not a list"     for i in range(0, len(L), n):         yield L[i:i+n] 
like image 614
Jed Smith Avatar asked Oct 26 '09 13:10

Jed Smith


People also ask

How do you split a list into N parts?

To split a list into N parts of approximately equal length with Python, we can use list comprehension. We define the chunkify function to split the lst list into n chunks. To do this, we use list comprehension to return slices of list with from index i to the end with n items in each chunk.

How do you split a list into evenly sized chunks?

The easiest way to split list into equal sized chunks is to use a slice operator successively and shifting initial and final position by a fixed number.


2 Answers

Here you go:

list_of_groups = zip(*(iter(the_list),) * group_size) 

Example:

print zip(*(iter(range(10)),) * 3) [(0, 1, 2), (3, 4, 5), (6, 7, 8)] 

If the number of elements is not divisible by N but you still want to include them you can use izip_longest but it is only available since python 2.6

izip_longest(*(iter(range(10)),) * 3) 

The result is a generator so you need to convert it into a list if you want to print it.

Finally, if you don't have python 2.6 and stuck with an older version but you still want to have the same result you can use map:

print map(None, *(iter(range(10)),) * 3) [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)] 

I'd like to add some speed comparison between the different methods presented so far:

python -m timeit -s 'from itertools import izip_longest; L = range(1000)' 'list(izip_longest(*(iter(L),) * 3))' 10000 loops, best of 3: 47.1 usec per loop  python -m timeit -s 'L = range(1000)' 'zip(*(iter(L),) * 3)' 10000 loops, best of 3: 50.1 usec per loop  python -m timeit -s 'L = range(1000)' 'map(None, *(iter(L),) * 3)' 10000 loops, best of 3: 50.7 usec per loop  python -m timeit -s 'L = range(1000)' '[L[i:i+3] for i in range(0, len(L), 3)]' 10000 loops, best of 3: 157 usec per loop  python -m timeit -s 'import itertools; L = range(1000)' '[list(group) for key, group in itertools.groupby(L, lambda k: k//3)]' 1000 loops, best of 3: 1.41 msec per loop 

The list comprehension and the group by methods are clearly slower than zip, izip_longest and map

like image 199
Nadia Alramli Avatar answered Oct 12 '22 16:10

Nadia Alramli


How about:

>>> n = 2 >>> l = [1,2,3,4,5,6,7,8,9] >>> [l[i:i+n] for i in range(0, len(l), n)] [[1, 2], [3, 4], [5, 6], [7, 8], [9]] 
like image 34
Steg Avatar answered Oct 12 '22 15:10

Steg