Breaking Python list into set-length list of lists

J

Jason

Hey everyone--

I'm pretty new to Python, & I need to do something that's incredibly
simple, but combing my Python Cookbook & googling hasn't helped me out
too much yet, and my brain is very, very tired & flaccid @ the
moment....

I have a list of objects, simply called "list". I need to break it
into an array (list of lists) wherein each sublist is the length of
the variable "items_per_page". So array[0] would go from array[0][0]
to array[0][items_per_page], then bump up to array[1][0] - array[1]
[items_per_page], until all the items in the original list were
accounted for.

What would be the simplest way to do this in Python? And yes, I
realize I should probably be taking Programming 101.....
 
M

Mensanator

Hey everyone--

I'm pretty new to Python, & I need to do something that's incredibly
simple, but combing my Python Cookbook & googling hasn't helped me out
too much yet, and my brain is very, very tired & flaccid @ the
moment....

I have a list of objects, simply called "list". �I need to break it
into an array (list of lists) wherein each sublist is the length of
the variable "items_per_page". �So array[0] would go from array[0][0]
to array[0][items_per_page], then bump up to array[1][0] - array[1]
[items_per_page], until all the items in the original list were
accounted for.

What would be the simplest way to do this in Python? �And yes, I
realize I should probably be taking Programming 101.....
items_per_page = 20
x = range(113)
layout = divmod(113,20)
if layout[1]>0:
pages = layout[0]+1
else:
pages = layout[0]
array = [ x[i*items_per_page:i*items_per_page+items_per_page] for i in xrange(pages)]
array
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39], [40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
53, 54, 55, 56, 57, 58, 59], [60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79], [80, 81, 82, 83, 84, 85, 86,
87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99], [100, 101, 102,
103, 104, 105, 106, 107, 108, 109, 110, 111, 112]]
 
T

Terry Reedy

Jason said:
I have a list of objects, simply called "list".

Bad idea.
I need to break it
into an array (list of lists) wherein each sublist is the length of
the variable "items_per_page". So array[0] would go from array[0][0]
to array[0][items_per_page], then bump up to array[1][0] - array[1]
[items_per_page], until all the items in the original list were
accounted for.

Assuming this is not homework, look at itertools module.

What would be the simplest way to do this in Python? And yes, I
realize I should probably be taking Programming 101.....

I guess it is not.
 
S

Steven D'Aprano

I have a list of objects, simply called "list".

Generally speaking, that's not a good choice of names, because it over-
writes ("shadows") the built-in function list().

I need to break it into
an array (list of lists) wherein each sublist is the length of the
variable "items_per_page". So array[0] would go from array[0][0] to
array[0][items_per_page], then bump up to array[1][0] - array[1]
[items_per_page], until all the items in the original list were
accounted for.


This may not be the simplest or most efficient way of doing it, but it
doesn't involve any advanced techniques other than slicing (which is
pretty fundamental to Python).

from string import lowercase # just some random data
list = list(lowercase)
items_per_page = 5
array = []
num_sublists = len(list)//items_per_page
if len(list) % items_per_page != 0:
.... num_sublists += 1
........ array.append(list[i*items_per_page:(i+1)*items_per_page])
....[['a', 'b', 'c', 'd', 'e'],
['f', 'g', 'h', 'i', 'j'],
['k', 'l', 'm', 'n', 'o'],
['p', 'q', 'r', 's', 't'],
['u', 'v', 'w', 'x', 'y'],
['z']]

There are other alternatives. Here's a more advanced technique:
ipp = 7 # use a shorter name
m, n = divmod(len(list), ipp)
array = [list[i*ipp:(i+1)*ipp] for i in range(m+bool(n))]
pprint(array)
[['a', 'b', 'c', 'd', 'e', 'f', 'g'],
['h', 'i', 'j', 'k', 'l', 'm', 'n'],
['o', 'p', 'q', 'r', 's', 't', 'u'],
['v', 'w', 'x', 'y', 'z']]
 
M

Mark Tolonen

Jason said:
Hey everyone--

I'm pretty new to Python, & I need to do something that's incredibly
simple, but combing my Python Cookbook & googling hasn't helped me out
too much yet, and my brain is very, very tired & flaccid @ the
moment....

I have a list of objects, simply called "list". I need to break it
into an array (list of lists) wherein each sublist is the length of
the variable "items_per_page". So array[0] would go from array[0][0]
to array[0][items_per_page], then bump up to array[1][0] - array[1]
[items_per_page], until all the items in the original list were
accounted for.

What would be the simplest way to do this in Python? And yes, I
realize I should probably be taking Programming 101.....
.... M=[]
.... for i in xrange(0,len(L),count):
.... M.append(L[i:i+count])
.... return M
....
L=range(18)
splitlist(L,3) [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17]]
splitlist(L,4)
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17]]

-Mark
 
G

Gerard Flanagan

Jason said:
Hey everyone--

I'm pretty new to Python, & I need to do something that's incredibly
simple, but combing my Python Cookbook & googling hasn't helped me out
too much yet, and my brain is very, very tired & flaccid @ the
moment....

I have a list of objects, simply called "list". I need to break it
into an array (list of lists) wherein each sublist is the length of
the variable "items_per_page". So array[0] would go from array[0][0]
to array[0][items_per_page], then bump up to array[1][0] - array[1]
[items_per_page], until all the items in the original list were
accounted for.

If you need to pad the last item:

def chunk( seq, size, pad=None ):
'''
Slice a list into consecutive disjoint 'chunks' of
length equal to size. The last chunk is padded if necessary.
>>> list(chunk(range(1,10),3)) [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> list(chunk(range(1,9),3)) [[1, 2, 3], [4, 5, 6], [7, 8, None]]
>>> list(chunk(range(1,8),3)) [[1, 2, 3], [4, 5, 6], [7, None, None]]
>>> list(chunk(range(1,10),1)) [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
>>> list(chunk(range(1,10),9)) [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
>>> for X in chunk([],3): print X
>>>
'''
n = len(seq)
mod = n % size
for i in xrange(0, n-mod, size):
yield seq[i:i+size]
if mod:
padding = [pad] * (size-mod)
yield seq[-mod:] + padding

If you search the list archive, there is surely an example which will do
the same for an arbitrary iterable (in general, you can't assume that
`len(seq)` will work for an iterable that is not a list, set or tuple).
But if you are just starting with Python, don't worry about this.
 
J

John Machin

Jason said:
Hey everyone--
I'm pretty new to Python, & I need to do something that's incredibly
simple, but combing my Python Cookbook & googling hasn't helped me out
too much yet, and my brain is very, very tired & flaccid @ the
moment....
I have a list of objects, simply called "list".  I need to break it
into an array (list of lists) wherein each sublist is the length of
the variable "items_per_page".  So array[0] would go from array[0][0]
to array[0][items_per_page], then bump up to array[1][0] - array[1]
[items_per_page], until all the items in the original list were
accounted for.

If you need to pad the last item:

def chunk( seq, size, pad=None ):
     '''
     Slice a list into consecutive disjoint 'chunks' of
     length equal to size. The last chunk is padded if necessary.

     >>> list(chunk(range(1,10),3))
     [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
     >>> list(chunk(range(1,9),3))
     [[1, 2, 3], [4, 5, 6], [7, 8, None]]
     >>> list(chunk(range(1,8),3))
     [[1, 2, 3], [4, 5, 6], [7, None, None]]
     >>> list(chunk(range(1,10),1))
     [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
     >>> list(chunk(range(1,10),9))
     [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
     >>> for X in chunk([],3): print X
     >>>
     '''
     n = len(seq)
     mod = n % size
     for i in xrange(0, n-mod, size):
         yield seq[i:i+size]
     if mod:
         padding = [pad] * (size-mod)
         yield seq[-mod:] + padding

If you search the list archive, there is surely an example which will do
the same for an arbitrary iterable (in general, you can't assume that
`len(seq)` will work for an iterable that is not a list, set or tuple).
But if you are just starting with Python, don't worry about this.

Aren't you making it out to be more mysterious than it needs to be?

Let's show the guy just a teensy bit of Python 102:

| >>> import string; data = string.ascii_lowercase
| >>> page_size = 6
| >>> pages = []
| >>> index = 0
| >>> for item in data:
| ... if not index:
| ... pages.append([])
| ... shelve_it = pages[-1].append
| ... index = (index + 1) % page_size
| ... shelve_it(item)
| ...
| >>> pages
| [['a', 'b', 'c', 'd', 'e', 'f'], ['g', 'h', 'i', 'j', 'k', 'l'],
['m', 'n', 'o', 'p', 'q', 'r'], ['s', 't', 'u', 'v', 'w', 'x'], ['y',
'z']]
| >>>
 
M

MRAB

Mensanator said:
Hey everyone--

I'm pretty new to Python, & I need to do something that's incredibly
simple, but combing my Python Cookbook & googling hasn't helped me out
too much yet, and my brain is very, very tired & flaccid @ the
moment....

I have a list of objects, simply called "list". �I need to break it
into an array (list of lists) wherein each sublist is the length of
the variable "items_per_page". �So array[0] would go from array[0][0]
to array[0][items_per_page], then bump up to array[1][0] - array[1]
[items_per_page], until all the items in the original list were
accounted for.

What would be the simplest way to do this in Python? �And yes, I
realize I should probably be taking Programming 101.....
items_per_page = 20
x = range(113)
layout = divmod(113,20)
if layout[1]>0:
pages = layout[0]+1
else:
pages = layout[0]
array = [ x[i*items_per_page:i*items_per_page+items_per_page] for i in xrange(pages)]
array
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39], [40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
53, 54, 55, 56, 57, 58, 59], [60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79], [80, 81, 82, 83, 84, 85, 86,
87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99], [100, 101, 102,
103, 104, 105, 106, 107, 108, 109, 110, 111, 112]]
>
Using list comprehension:
>>> my_list = range(113)
>>> items_per_page = 20
>>>
>>> array = [my_list[start : start + items_per_page] for start in range(0, len(my_list), items_per_page)]
>>>
>>> array
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
38, 39], [40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 59], [60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79], [80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99], [100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 110, 111, 112]]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top