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?
Answers:
Try this, using list comprehensions:
[array[i:i+10] for i in range(0, len(array)-9, 10)]
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.
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) ]
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
]
]
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?
Try this, using list comprehensions:
[array[i:i+10] for i in range(0, len(array)-9, 10)]
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.
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) ]
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
]
]