Michael Puckett - 1 year ago 65
Python Question

# Creating sublists

The opposite of list flattening.

Given a list and a length n return a list of sub lists of length n.

``````def sublist(lst, n):
sub=[] ; result=[]
for i in lst:
sub+=[i]
if len(sub)==n: result+=[sub] ; sub=[]
if sub: result+=[sub]
return result
``````

An example:

If the list is:

``````[1,2,3,4,5,6,7,8]
``````

And n is:

``````3
``````

Return:

``````[[1, 2, 3], [4, 5, 6], [7, 8]]
``````

Is there a more eloquent / concise way?

An aside, what is preferred when appending lists to lists (in the context above):

``````list1+=[list2]
``````

Or:

``````list1.append(list2)
``````

Given that (according to Summerfeild's 'Programming in Python 3') they are the same?

Thanks.

Such a list of lists could be constructed using a list comprehension:

``````In [17]: seq=[1,2,3,4,5,6,7,8]
In [18]: [seq[i:i+3] for i in range(0,len(seq),3)]
Out[18]: [[1, 2, 3], [4, 5, 6], [7, 8]]
``````

There is also the grouper idiom:

``````In [19]: import itertools
In [20]: list(itertools.izip_longest(*[iter(seq)]*3))
Out[20]: [(1, 2, 3), (4, 5, 6), (7, 8, None)]
``````

but note that missing elements are filled with the value None. izip_longest can take a `fillvalue` parameter as well if something other than None is desired.

`list1+=[list2]` -- noting the brackets this time -- is equivalent to `list1.append(list2)`. My highest priority when writing code is readability, not speed. For this reason, I would go with `list1.append(list2)`. Readability is subjective, however, and probably is influenced greatly by what idioms you're familiar with.

Happily, in this case, readability and speed seem to coincide:

``````In [41]: %timeit list1=[1,2,3]; list1.append(list2)
1000000 loops, best of 3: 612 ns per loop

In [42]: %timeit list1=[1,2,3]; list1+=[list2]
1000000 loops, best of 3: 847 ns per loop
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download