split a num list into sublists with a specific order

Question:

I have a list of numbers from range 1 to n and I want to split those numbers into x sublists where each sublist contains less than 30 numbers. The amount of sublists is the least amount i need depending on the total of numbers in a list so for example if I had 68 I’d need 3 sublists at least where the numbers are split between them. How would I go about splitting them so each sublist has the next number in the original list to get an output like this

a = []
for i in range(68):
   a.append(i)

#code

output:
[[1,6,7,12,13,18,19,24....][2,5,8,11,14,17,20,23....][3,4,9,10,15,16,21,22....]]

or if I need 4 sub lists it’d go like this

output:
[[1,8,9,16,17....][2,7,10,15,18][3,6,11,14,19][4,5,12,13,20,21....]]

edit: this isn’t the exact same question as Splitting a python list into 4 sub-lists that are as even as possible since I don’t want the iteration to go back to the beginning once it finishes a loop. I want it to start iterating again from the bottom like this

[0,13,14,28,29,42,43,56,57]
[1,12,15,27,30,41,44,55,58]
[2,11,16,26,31,40,45,54,59]
[3,10,17,25,32,39,46,53,60]
[4,9,19,24,33,38,47,52,61]
[5,8,20,23,34,37,48,51,62]
[6,7,21,22,35,36,49,50,63,64]
Asked By: Thomas vincent

||

Answers:

For three sub lists sublists = [[], [], []]:

  • First iteration place the next three items in sublists[0] , then sublists[1] then sublists[2]
  • Second iteration place the next three items in sublists[2] , then sublists[1] then sublists[0]
  • Third iteration switch the order again
  • continue flipping the order every three items till iteration is done

To make it generic for n sublist:

  • sublists = [[] for _ in range(n)]
  • get n items and put them in sublists[0], …, sublist[n-1], sublist[n]
  • get next n items and put them in sublists[n], sublist[n-1],…, sublist[0]
  • repeat
Answered By: wwii

Let’s say you have

N = 68 # Number of elements
M = 30 # Max list size

First the number of sublists:

count = math.ceil(N / M)

Or, without ceil:

count = (N + M - 1) // M

The pattern of where you put each element of range(N) goes like this:

0, 1, 2, ..., count - 1, count - 1, count - 2, ..., 1, 0, 0, 1, 2, ...

Every count elements, you flip the order. So you can make a flip every count elements:

subs = [[] for _ in range(count)]
for i in range(N):
    index = i % count
    if (i // count) % 2:
        index = count - index - 1
    subs[index].append(i + 1)

You can also look at it the other way: the pattern of elements in a sublist is (up to some offset):

1, 2 * count, 2 * count + 1, 4 * count, 4 * count + 1, 6 * count, ...

You can express this as a nested list comprehension:

subs = [[j + (count - i if (j // count) % 2 else i + 1) for j in range(0, N - i, count)] for i in range(count)]
Answered By: Mad Physicist
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.