0

注意:根据某些人的建议,我将此问题重新发布到codereview站点


我想使用另一个包含每个拆分长度的列表来拆分一个列表。

例如。

>>> print list(split_by_lengths(list('abcdefg'), [2,1]))
... [['a', 'b'], ['c'], ['d', 'e', 'f', 'g']]
>>> print list(split_by_lengths(list('abcdefg'), [2,2]))
... [['a', 'b'], ['c', 'd'], ['e', 'f', 'g']]    
>>> print list(split_by_lengths(list('abcdefg'), [2,2,6]))
... [['a', 'b'], ['c', 'd'], ['e', 'f', 'g']]
>>> print list(split_by_lengths(list('abcdefg'), [1,10]))
... [['a'], ['b', 'c', 'd', 'e', 'f', 'g']]
>>> print list(split_by_lengths(list('abcdefg'), [2,2,6,5]))
... [['a', 'b'], ['c', 'd'], ['e', 'f', 'g']]

如您所见,如果长度列表未涵盖所有列表,我会将其余元素附加为附加子列表。另外,如果长度列表产生更多要拆分的列表中的元素,我想避免最后出现空列表。

我已经有一个可以按我想要的方式工作的功能:

def take(n, iterable):
    "Return first n items of the iterable as a list"
    return list(islice(iterable, n))

def split_by_lengths(list_, lens):
    li = iter(list_)
    for l in lens:
        elems = take(l,li)
        if not elems:
            break
        yield elems
    else:
        remaining = list(li)
        if remaining:
           yield remaining

但我想知道是否有一种更 Pythonic 的方式来编写这样的函数。

注意:take(n, iterable)Itertools Recipes中获取:

4

1 回答 1

5

您可以使用以下方法执行此操作itertools.islice

from itertools import islice

def split_by_lengths(seq, num):
    it = iter(seq)
    for x in num:
        out = list(islice(it, x))
        if out:
            yield out
        else:
            return   #StopIteration 
    remain = list(it)
    if remain:
        yield remain

演示:

>>> list(split_by_lengths(list('abcdefg'), [2,1]))
[['a', 'b'], ['c'], ['d', 'e', 'f', 'g']]
>>> list(split_by_lengths(list('abcdefg'), [2,2]))
[['a', 'b'], ['c', 'd'], ['e', 'f', 'g']]
>>> list(split_by_lengths(list('abcdefg'), [2,2,6]))
[['a', 'b'], ['c', 'd'], ['e', 'f', 'g']]
>>> print list(split_by_lengths(list('abcdefg'), [1,10]))
[['a'], ['b', 'c', 'd', 'e', 'f', 'g']]

上述版本的较短版本,但请注意,与第一个答案不同,一旦迭代器用尽,这不会缩短。

def split_by_lengths(seq, num):
    it = iter(seq)
    out =  [x for x in (list(islice(it, n)) for n in num) if x]
    remain = list(it)
    return out if not remain else out + [remain]
于 2014-04-04T08:42:02.803 回答