假设我有一个任意长度的列表,L:
L = list(range(1000))
Run Code Online (Sandbox Code Playgroud)
将该列表拆分成组的最佳方法是n什么?这是我能够提出的最好的结构,并且由于某种原因,它不觉得它是完成任务的最佳方式:
n = 25
for i in range(0, len(L), n):
chunk = L[i:i+25]
Run Code Online (Sandbox Code Playgroud)
是否有内置功能,我缺少这个?
编辑:早期的答案是将我的for循环重新编写为listcomp,这不是主意; 你基本上以不同的形式给我我的确切答案.我正在看是否有另一种方法可以实现这一点,就像.split列表上的假设一样.我也在昨晚写的一些代码中使用它作为生成器:
def split_list(L, n):
assert type(L) is list, "L is not a list"
for i in range(0, len(L), n):
yield L[i:i+n]
Run Code Online (Sandbox Code Playgroud)
Nad*_*mli 117
干得好:
list_of_groups = zip(*(iter(the_list),) * group_size)
Run Code Online (Sandbox Code Playgroud)
例:
print zip(*(iter(range(10)),) * 3)
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
Run Code Online (Sandbox Code Playgroud)
如果元素的数量不能被N整除,但你仍然希望包含它们,你可以使用izip_longest,但它只能从python 2.6开始使用
izip_longest(*(iter(range(10)),) * 3)
Run Code Online (Sandbox Code Playgroud)
结果是生成器,因此如果要打印它,则需要将其转换为列表.
最后,如果你没有python 2.6并且坚持使用旧版本但是你仍然希望获得相同的结果,那么你可以使用map:
print map(None, *(iter(range(10)),) * 3)
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]
Run Code Online (Sandbox Code Playgroud)
我想在目前提供的不同方法之间添加一些速度比较:
python -m timeit -s 'from itertools import izip_longest; L = range(1000)' 'list(izip_longest(*(iter(L),) * 3))'
10000 loops, best of 3: 47.1 usec per loop
python -m timeit -s 'L = range(1000)' 'zip(*(iter(L),) * 3)'
10000 loops, best of 3: 50.1 usec per loop
python -m timeit -s 'L = range(1000)' 'map(None, *(iter(L),) * 3)'
10000 loops, best of 3: 50.7 usec per loop
python -m timeit -s 'L = range(1000)' '[L[i:i+3] for i in range(0, len(L), 3)]'
10000 loops, best of 3: 157 usec per loop
python -m timeit -s 'import itertools; L = range(1000)' '[list(group) for key, group in itertools.groupby(L, lambda k: k//3)]'
1000 loops, best of 3: 1.41 msec per loop
Run Code Online (Sandbox Code Playgroud)
列表理解和按方法分组显然比zip,izip_longest和map慢
Ste*_*teg 47
怎么样:
>>> n = 2
>>> l = [1,2,3,4,5,6,7,8,9]
>>> [ l[i:i+n] for i in range(0, len(l), n) ]
[[1, 2], [3, 4], [5, 6], [7, 8], [9]]
Run Code Online (Sandbox Code Playgroud)
Ste*_*202 41
甲的Python配方(在Python 2.6,使用itertools.izip_longest):
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return itertools.zip_longest(*args, fillvalue=fillvalue)
Run Code Online (Sandbox Code Playgroud)
用法示例:
>>> list(grouper(3, range(9)))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
>>> list(grouper(3, range(10)))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]
Run Code Online (Sandbox Code Playgroud)
如果你想让最后一个组比其他组更短而不是填充fillvalue,那么你可以改变代码如下:
>>> def mygrouper(n, iterable):
... args = [iter(iterable)] * n
... return ([e for e in t if e != None] for t in itertools.zip_longest(*args))
...
>>> list(mygrouper(3, range(9)))
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
>>> list(mygrouper(3, range(10)))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
Run Code Online (Sandbox Code Playgroud)
u0b*_*6ae 13
Itertools.groupby是一个很好的工具,这里只是通过使用整数除法来分割整数列表:
>>> for key, group in itertools.groupby(range(10), lambda k: k//3):
... print key, list(group)
...
0 [0, 1, 2]
1 [3, 4, 5]
2 [6, 7, 8]
3 [9]
Run Code Online (Sandbox Code Playgroud)
(列表必须从0开始才能以完整的组开头.)
n = 25
list_of_lists = [L[i:i+n] for i in range(0, len(L), n)]
Run Code Online (Sandbox Code Playgroud)
它为您提供了列表清单 [[0..24], [25..49], ..]
如果len(L) % n不为0,则最后一个元素的(list_of_lists[-1])长度为len(L)%n.
| 归档时间: |
|
| 查看次数: |
51499 次 |
| 最近记录: |