Split up long list of 100 values to a list with small arrays of 10 values in it, python

Question:

I have a list of 100 values that i would like to split up to a list with arrays in it were every array holds 10 values.

What I have, for ex:

array = [1,2,3,4,5,6,7,7,8,9,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8............]

What I want, for ex:

newarray = [[0,1,2,3,4,5,6,7,7,8,9],[1,2,3,4,5,6,7,8,9,1],[2,3,4,5,6,7,8............]]

I want to do this so that I can call for newArray[4] and get 10 values.

This is what i have tried:

for i in range(len(values)):
    a = []
    for j in range(10): 
        a.append(values[j])
    val.append(a)

    print(val)

Problem is that i now get all the first ten values in every different array.

What am I doing wrong?

Asked By: Thosc1

||

Answers:

Try this, using list comprehensions:

[array[i:i+10] for i in range(0, len(array)-9, 10)]
Answered By: Óscar López

There are certainly other (arguably more pythonic) ways to solve this problem, but here is what’s wrong with your code:

In this part:

...
    for j in range(10): 
        a.append(values[j])
...

The index j will be the same for each value of i. The value you want to append, should be offset based on i.

Here is one approach:

...
    for j in range(10): 
        a.append(values[(i*10)+j])
...

This way when i = 0, you’ll append the items from values[0] through values[9]. Likewise, when i=1, you’ll append the items from values[10] through values[19] and so on.

Answered By: pault

The reason you’re only getting the first ten values is that you’re only iterating over the first ten values, just for len(values) iterations. So, instead of ending up with a list of 10 sublists, each with 10 values, you get a list with 100 sublists, each with the first 10 values of the original list. To fix this, you need to change your outer loop variable to be range(0, len(values) - 10, 10) and your inner variable to be range(i, i + 10). Of course, then you could be left with a little chunk at the end which you’d have to deal with, but in your case len(values) % 10 == 0 so you should be fine there. Putting this all together, we have:

val = []
for i in range(0, len(values) - 10, 10):
    val.append(values[i: i + 10])

Doing this via list-comprehension:

val = [ values[i : i + 10] for i in range(0, len(values) - 10, 10) ]
Answered By: Woody1193

Here is my version with 2 function, one is generator and the second one that creates a new list. Both of them uses generics.

from collections.abc import Iterator
from typing import TypeVar


ChunkItem = TypeVar("ChunkItem")


def generate_chunks(
    items: list[ChunkItem], size: int
) -> Iterator[list[ChunkItem]]:
    for i in range(0, len(items), size):
        if chunk_records := items[i: i + size]:
            yield chunk_records


def make_chunks(items: list[ChunkItem], size: int) -> list[list[ChunkItem]]:
    return [
        items[size * i : size * i + size]
        for i in range(len(items) // size + 1)
        if items[
            size * i: size * i + size
        ]
    ]
Answered By: Vladimir Prudnikov
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.