Python : Get many list from a list [duplicate]
Possible Duplicate:
How do you split a list into evenly sized chunks in Python?
Hi,
I would l开发者_StackOverflowike to split a list in many list of a length of x elements, like:
a = (1, 2, 3, 4, 5)
and get :
b = (
(1,2),
(3,4),
(5,)
)
if the length is set to 2 or :
b = (
(1,2,3),
(4,5)
)
if the length is equal to 3 ...
Is there a nice way to write this ? Otherwise I think the best way is to write it using an iterator ...
Here's how I'd do it. Iteration, but in a list comprehension. Note the type gets mixed; this may or may not be desired.
def sublist(seq, length):
return [seq[i:i + length] for i in xrange(0, len(seq), length)]
Usage:
>>> sublist((1, 2, 3, 4, 5), 1)
[(1,), (2,), (3,), (4,), (5,)]
>>> sublist([1, 2, 3, 4, 5], 2)
[[1, 2], [3, 4], [5]]
>>> sublist('12345', 3)
['123', '45']
>>> sublist([1, 2, 3, 4, 5], 73)
[[1, 2, 3, 4, 5]]
>>> sublist((1, 2, 3, 4, 5), 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in sublist
ValueError: xrange() arg 3 must not be zero
Of course, you can easily make it produce a tuple
too if you want - replace the list comprehension [...]
with tuple(...)
. You could also replace seq[i:i + length]
with tuple(seq[i:i + length])
or list(seq[i:i + length])
to make it return a fixed type.
The itertools module documentation. Read it, learn it, love it.
Specifically, from the recipes section:
import itertools
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return itertools.izip_longest(fillvalue=fillvalue, *args)
Which gives:
>>> tuple(grouper(3, (1,2,3,4,5)))
((1, 2, 3), (4, 5, None))
which isn't quite what you want...you don't want the None
in there...so. a quick fix:
>>> tuple(tuple(n for n in t if n) for t in grouper(3, (1,2,3,4,5)))
((1, 2, 3), (4, 5))
If you don't like typing the list comprehension every time, we can move its logic into the function:
def my_grouper(n, iterable):
"my_grouper(3, 'ABCDEFG') --> ABC DEF G"
args = [iter(iterable)] * n
return tuple(tuple(n for n in t if n)
for t in itertools.izip_longest(*args))
Which gives:
>>> tuple(my_grouper(3, (1,2,3,4,5)))
((1, 2, 3), (4, 5))
Done.
From the python docs on the itertools module:
from itertools import izip_longest
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
Example:
>>> tuple(grouper(3, (1, 2, 3, 4, 5, 6, 7)))
((1, 2, 3), (4, 5, 6), (7, None, None))
精彩评论