可能是重复的问题,但我找不到任何相关内容。
我有一个非常长的迭代器(10000个元素),我需要每次迭代500个元素。如果我的迭代器是range(10000)
,那么代码应该如下所示:
Iteration #1: 0, 1, 2, ... 497, 498, 499
Iteration #2: 1, 2, 3, ... 498, 499, 500
Iteration #3: 2, 3, 4, ... 499, 500, 501
Iteration #4: 3, 4, 5, ... 500, 501, 502
...
Iteration #9500: 9499, 9500, 9501 ... 9996, 9997, 9998
Iteration #9501: 9500, 9501, 9502 ... 9997, 9998, 9999
等等。这里有一个方法:
def nwise_slice(lst, n):
for i in range(len(lst) - n + 1):
yield lst[i:i + n]
然而,这种方法不能与惰性迭代器一起使用。我尝试使用迭代器创建解决方案,并从 itertools
的 pairwise
和 consume
配方中进行了适应(请参见此处)以创建以下内容:
import itertools
def nwise_iter(lst, n):
iters = itertools.tee(lst, n)
for idx, itr in enumerate(iters):
next(itertools.islice(itr, idx, idx), None)
for group in zip(*iters):
yield group
这个方法与使用list
相同(虽然返回的是一个tuple
而不是list
,但对我来说无关紧要)。我认为它不会创建很多不必要的切片。这种解决方案适用于非可切片迭代器,如文件(我计划使用)。然而,itertools
的解决方案速度慢了2倍:
In [4]: %timeit list(nwise_slice(list(range(10000)), 500))
46.9 ms ± 729 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [5]: %timeit list(nwise_iter(list(range(10000)), 500))
102 ms ± 3.95 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
我不想把所有的测试数据加载到内存中,以利用slice
方法。有没有更有效的方法来完成这个操作?
grouper()
函数。 - martineau(1, 2, 3), (4, 5, 6)
而不是(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6)
。 - iz_more_itertools
库list(more_itertools.windowed(range(10000), 500))
。 - pylang