我想使用另一个列表的值作为分割范围将一个列表分割成块。
indices = [3, 5, 9, 13, 18]
my_list = ['a', 'b', 'c', ..., 'x', 'y', 'z']
所以基本上,从范围中分割 my_list:
my_list[:3], mylist[3:5], my_list[5:9], my_list[9:13], my_list[13:18], my_list[18:]
我尝试将索引分成 2 个块,但结果不是我需要的。
[indices[i:i + 2] for i in range(0, len(indices), 2)]
我的实际列表长度是1000。
您也可以使用简单的 python 来完成。
indices = [3, 5, 9, 13, 18]
my_list = list('abcdefghijklmnopqrstuvwxyz')
使用列表理解。
[(my_list+[''])[slice(ix,iy)] for ix, iy in zip([0]+indices, indices+[-1])]
[['a', 'b', 'c'],
['d', 'e'],
['f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm'],
['n', 'o', 'p', 'q', 'r'],
['s', 't', 'u', 'v', 'w', 'x', 'y', 'z']]
dict(((ix,iy), (my_list+[''])[slice(ix,iy)]) for ix, iy in zip([0]+indices, indices+[-1]))
{(0, 3): ['a', 'b', 'c'],
(3, 5): ['d', 'e'],
(5, 9): ['f', 'g', 'h', 'i'],
(9, 13): ['j', 'k', 'l', 'm'],
(13, 18): ['n', 'o', 'p', 'q', 'r'],
(18, -1): ['s', 't', 'u', 'v', 'w', 'x', 'y', 'z']}
itertools.zip_longest
[my_list[a:b] for a,b in it.zip_longest([0]+indices, indices)]
[['a', 'b', 'c'],
['d', 'e'],
['f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm'],
['n', 'o', 'p', 'q', 'r'],
['s', 't', 'u', 'v', 'x', 'y', 'z']]
一点代码高尔夫的乐趣:
map(my_list.__getitem__, map(lambda s: slice(*s), it.zip_longest([0]+indices, indices)))
使用
itertools.tee
和 pairwise
的一种方法:
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
chunks = [my_list[i:j] for i, j in pairwise([0, *indices, len(my_list)])]
print(chunks)
输出:
[['a', 'b', 'c'],
['d', 'e'],
['f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm'],
['n', 'o', 'p', 'q', 'r'],
['s', 't', 'u', 'v', 'w', 'x', 'y', 'z']]
如果
numpy
是一个选项,请使用 numpy.array_split
,这意味着:
import numpy as np
np.array_split(my_list, indices)
输出:
[array(['a', 'b', 'c'], dtype='<U1'),
array(['d', 'e'], dtype='<U1'),
array(['f', 'g', 'h', 'i'], dtype='<U1'),
array(['j', 'k', 'l', 'm'], dtype='<U1'),
array(['n', 'o', 'p', 'q', 'r'], dtype='<U1'),
array(['s', 't', 'u', 'v', 'w', 'x', 'y', 'z'], dtype='<U1')]
CypherX的解决方案可以简化,我会添加对索引列表中索引为0或重复项的边缘情况的检查
[my_list[s:e] for s, e in zip([0] + indices, indices + [len(my_list)]) if my_list[s:e]]