与列表展平相反。
给定列表和长度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的“Python 3编程”),它们是一样的吗?
感谢。
答案 0 :(得分:19)
可以使用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]]
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。如果需要除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
答案 1 :(得分:7)
以下内容(x
是您的列表):
[x[i:i+3] for i in range(0, len(x), 3)]
对n!=3
进行概括,这是微不足道的。
至于你的第二个问题,它们是等价的,所以我认为这是一个风格问题。但是,请确保您不是confusing append
with extend
。
答案 2 :(得分:5)
此函数可以采用任何类型的迭代(不仅是已知长度的序列):
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]]
答案 3 :(得分:3)
您听说过boltons
吗?
相同 - 但显然遗漏了
Boltons
是一组纯Python实用工具,其精神与标准库
它有你想要的,内置的,称为chunked
from boltons import iterutils
iterutils.chunked([1,2,3,4,5,6,7,8], 3)
输出:
[[1, 2, 3], [4, 5, 6], [7, 8]]
boltons
中的更具吸引力的是chunked
作为迭代器,称为chunked_iter
,所以你不要#39;需要将整个东西存储在内存中。干净吧?
答案 4 :(得分:1)
我认为这个split函数能够满足您的需求(尽管它适用于任何迭代器而不仅仅是列表):
from itertools import islice
def take(n, it):
"Return first n items of the iterable as a list"
return list(islice(it, n))
def split(it, size):
it = iter(it)
size = int(size)
ret = take(size, it)
while ret:
yield ret
ret = take(size, it)
编辑:关于你的帮助,我总是使用list.append(blah),因为它对我来说感觉更加惯用,但我相信它们在功能上是等价的。
答案 5 :(得分:0)
我知道,它看起来像brainfuck,但有效:
>>> a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
>>> n = 3
>>> [i for j in [[a[t:t+n] for x in a[:1:t+1] if (t%n)==False] for t in range(len(a))] for i in j]
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]
>>> n = 4
>>> [i for j in [[a[t:t+n] for x in a[:1:t+1] if (t%n)==False] for t in range(len(a))] for i in j]
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15]]
答案 6 :(得分:0)
对于某些特定情况,使用numpy包可能很有用。在这个包中你有一个reshape例程:
import numpy as np
x = np.array([1,2,3,4,5,6])
np.reshape(x, (-1,3))
但是,如果不是n的乘法,此解决方案将不会填充您的列表。