-1

How could I convert a list into a nested list with increasing size of the sublists?

For example, from

[1, 2, 3, 4, 5, 6]

to

[[1], [2, 3], [4, 5, 6]]
timgeb
  • 76,762
  • 20
  • 123
  • 145
Ivan
  • 9

4 Answers4

2

I'd do this with islices over an iterator of the original list. This way I can just specifiy the number of elements to take without having to worry at which position I am currently at. (In addition, the following code works with any iterable.)

def increasing_chunks(iterable):
    it = iter(iterable)
    i = 1

    while True:
        chunk = list(islice(it, i))
        if not chunk:
            break
        yield chunk
        i += 1

The last chunk might be truncated to whatever amount of elements the iterator had left.

Demo:

>>> list(increasing_chunks([1, 2, 3, 4, 5, 6]))
[[1], [2, 3], [4, 5, 6]]
>>> list(increasing_chunks([1, 2, 3, 4, 5, 6, 7, 8]))
[[1], [2, 3], [4, 5, 6], [7, 8]]

If you want to discard truncated chunks, adjust the code as follows:

def increasing_chunks_strict(iterable):
    it = iter(iterable)
    i = 1

    while True:
        chunk = list(islice(it, i))
        if len(chunk) < i:
            break
        yield chunk
        i += 1

Now, truncated chunks are not included in the result.

>>> list(increasing_chunks_strict([1, 2, 3, 4, 5, 6]))
[[1], [2, 3], [4, 5, 6]]
>>> list(increasing_chunks_strict([1, 2, 3, 4, 5, 6, 7, 8]))
[[1], [2, 3], [4, 5, 6]]
timgeb
  • 76,762
  • 20
  • 123
  • 145
1

As a follow up to timgeb's solution, without itertools, you need to keep track of the index:

l = [1, 2, 3, 4, 5, 6]

i, slice_length = 0, 1
result = []
while i < len(l):
    result.append(l[i:i + slice_length])
    i += slice_length
    slice_length += 1

print(result)
# [[1], [2, 3], [4, 5, 6]]
slider
  • 12,810
  • 1
  • 26
  • 42
0

Several itertools and enumerate to the rescue:

from itertools import count, accumulate as acc, takewhile as tw

lst = [1, 2, 3, 4, 5, 6]
[lst[c:c+i] for i, c in enumerate(tw(lambda x: x < len(lst), acc(count())), 1)]
# [[1], [2, 3], [4, 5, 6]]
user2390182
  • 72,016
  • 6
  • 67
  • 89
0

Assuming that you list length has the correct length for the last chunk to have the correct size, you can use list sum, range and list comprehension to solve your problem in few lines:

l = [1, 2, 3, 4, 5, 6]
slices = range(1, (len(l) + 1)/2 + 1)
result = [l[sum(slices[:s-1]):sum(slices[:s-1])+s] for s in slices]
Aurora Wang
  • 1,822
  • 14
  • 22