2

I hope this question isn't a duplicate; I found similar ones but not exactly what I need.

I want an efficient way to split a list into n sublists where each index goes to a different list until we reach the nth index and then the next n indexes go to the lists we already have, in the same order, and so on...

For example, given the following list:

l = [1,1,1,2,2,2,3,3,3]
n = 3

In this case I need to split the list into 3 lists with this desired output:

[[1,2,3],[1,2,3],[1,2,3]]

I can make n for loops that will skip every nth step, but I'm sure there is a better way.

Ortal Turgeman
  • 143
  • 4
  • 14

3 Answers3

8

Using zip and list comprehension

l = [1,1,1,2,2,2,3,3,3]
n = 3
print([list(i) for i in zip(*[l[i:i+n] for i in range(0, len(l), n)])])

Output:

[[1, 2, 3], [1, 2, 3], [1, 2, 3]]

Note: You can also use from itertools import izip_longest if the chunks are uneven.

Rakesh
  • 81,458
  • 17
  • 76
  • 113
1

For the loop method you describe, see How do you split a list into evenly sized chunks?

A better way would be to use a 3rd party library such as numpy. This takes advantage of vectorised computations:

Example #1

import numpy as np

l = np.array([1,1,1,2,2,2,3,3,3])
n = 3

res = l.reshape((len(l)/n), n).T

print(res)

array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

Example #2

import numpy as np

l = np.array([1,2,3,4,5,6,7,8])
n = 4

res = l.reshape((len(l)/n, n)).T

print(res)

array([[1, 5],
       [2, 6],
       [3, 7],
       [4, 8]])
jpp
  • 159,742
  • 34
  • 281
  • 339
  • i saw the question "How do you split a list into evenly sized chunks?" and all other similar questions but it's not the same kind of chunks. you should know since your answer has the right outcome – Ortal Turgeman Apr 24 '18 at 12:22
  • @OrtalTurgeman, Well, the logic still works (still update). Up to you, though, if you like lists of lists. – jpp Apr 24 '18 at 12:27
  • you're answer seems to be good and clean but 'numpy' requires installation, it's not a base python package (i'm using python 2.7), so i preferred the first answer. thanks – Ortal Turgeman Apr 24 '18 at 12:32
0

i found another answer, very simple, using modulo:

l = [1,2,3,4,5,6,7,8]
n = 4
for i in range (n):
    a.append([])
for i in range(len(l)):
    a[i%n].append(l[i])

output:

[[1, 5], [2, 6], [3, 7], [4, 8]]
Ortal Turgeman
  • 143
  • 4
  • 14