在Python中对列表进行分段

13

我正在寻找一种Python内置的函数(或机制),可以将一个列表分割成所需的段长(而不会改变输入列表)。以下是我已经拥有的代码:

>>> 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]]

相关内容请参考:https://dev59.com/2XI-5IYBdhLWcg3wVWli - jfs
3个回答

23

您可以使用列表推导式实现:

>>> 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]]

4
你还可以将这个变成一个生成器,即 (a[x:x+seg_length] for x in range(0,len(a),seg_length)),对于大型序列来说更加高效。 - mhawke

5

你需要如何使用输出?如果你只需要迭代它,最好创建一个可迭代对象,该对象会产生你的分组:

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

使用示例:

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

如果您只是循环遍历结果,那么与一次性在内存中构建整个列表相比,这种方法使用的内存要少得多,因为它一次只构建一个子集:

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

+1. 这是一个非常明智的方法。如果我的输入数据增加,我会记住这个方法。 - kjfletch

2

虽然输出不同,但我仍然认为grouper函数很有用:

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

适用于Python2.4和2.5的izip_longest不存在:

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

一些演示代码和输出:

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

输出结果为:[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接