创建子列表

2024-05-17 16:56:39 发布

您现在位置:Python中文网/ 问答频道 /正文

列表扁平化的反面。

给定一个列表和一个长度n返回一个长度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

例如:

如果列表是:

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

n是:

3

返回:

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

有没有更雄辩/简洁的方法?

另外,在将列表附加到列表时(在上面的上下文中)首选的是什么:

list1+=[list2]

或:

list1.append(list2)

假设(根据Summerfeild的“Python3编程”)它们是相同的?

谢谢。


Tags: 方法in列表forlenreturnifdef
3条回答

此函数可以接受任何类型的iterable(不仅仅是已知长度的序列):

import itertools

def grouper(n, it):
    "grouper(3, 'ABCDEFG') --> ABC DEF G"
    it = iter(it)
    return iter(lambda: list(itertools.islice(it, n)), [])

print(list(grouper(3, [1,2,3,4,5,6,7,8,9,10])))
# [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

下面(其中x是您的列表)怎么样

 [x[i:i+3] for i in range(0, len(x), 3)]

这对于n!=3的泛化来说是微不足道的。

至于你的第二个问题,它们是等价的,所以我认为这是一个风格问题。但是,一定要确保你不是confusing ^{} with ^{}

这样的列表列表可以使用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]]

还有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)]

但请注意,缺少的元素都用值None填充。izip_longest也可以使用fillvalue参数,前提是不需要任何参数。


list1+=[list2]——这次注意括号——相当于list1.append(list2)。我写代码的最高优先级是可读性, 不是速度。出于这个原因,我会选择list1.append(list2)。然而,可读性是主观的,而且可能会受到你所熟悉的成语的很大影响。

令人高兴的是,在这种情况下,可读性和速度似乎是一致的:

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

相关问题 更多 >