在Python中分割列表

Segment a list in Python

我正在寻找一个python内置的函数(或机制),将一个列表分段为所需的段长度(而不改变输入列表)。这是我已经拥有的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> def split_list(list, seg_length):
...     inlist = list[:]
...     outlist = []
...    
...     while inlist:
...         outlist.append(inlist[0:seg_length])
...         inlist[0:seg_length] = []
...    
...     return outlist
...
>>> alist = range(10)
>>> split_list(alist, 3)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]


您可以使用列表理解:

1
2
3
4
>>> seg_length = 3
>>> a = range(10)
>>> [a[x:x+seg_length] for x in range(0,len(a),seg_length)]
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]


您需要如何使用输出?如果您只需要对其进行迭代,那么最好创建一个ITerable,它生成您的组:

1
2
3
4
5
6
7
8
9
10
def split_by(sequence, length):
    iterable = iter(sequence)
    def yield_length():
        for i in xrange(length):
             yield iterable.next()
    while True:
        res = list(yield_length())
        if not res:
            return
        yield res

用法示例:

1
2
3
>>> alist = range(10)
>>> list(split_by(alist, 3))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

如果您只是循环结果,那么这比一次在内存中构建整个列表所用的内存要少得多,因为它一次只构造一个子集:

1
2
3
4
5
6
7
>>> for subset in split_by(alist, 3):
...     print subset
...
[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
[9]


不同的输出,我仍然认为grouper函数有帮助:

1
2
3
4
from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return izip_longest(*args, fillvalue=fillvalue)

对于没有Izip_最长的python2.4和2.5:

1
2
3
from itertools import izip, chain, repeat
def grouper(iterable, n, padvalue=None):
    return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)

一些演示代码和输出:

1
2
alist = range(10)
print list(grouper(alist, 3))

输出:[(0,1,2),(3,4,5),(6,7,8),(9,无,无)]