如何在迭代器上高效地迭代“nwise”

2024-04-25 20:35:01 发布

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

可能是复制品,但我什么也找不到。你知道吗

我有一个很长的迭代器(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]

但是,这不适用于懒惰的迭代器。我尝试使用迭代器创建一个解决方案,并根据itertoolspairwiseconsume配方(请参见here)进行改编,以创建以下内容:

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

这是一样的(尽管产生了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方法而必须将所有测试数据加载到内存中。有没有更有效的方法?你知道吗


Tags: 方法infordefslicerangelistms
1条回答
网友
1楼 · 发布于 2024-04-25 20:35:01

如何使用dequememoize您的项目?你知道吗

from collections import deque

def nwise_slice(it, n):
    deq = deque((), n)
    for x in it:
        deq.append(x)
        if len(deq)==n: yield deq

my_range = range(8)
for sub in nwise_slice(my_range, 5):
    print(sub)
# =>
# deque([0, 1, 2, 3, 4], maxlen=5)
# deque([1, 2, 3, 4, 5], maxlen=5)
# deque([2, 3, 4, 5, 6], maxlen=5)
# deque([3, 4, 5, 6, 7], maxlen=5)

相关问题 更多 >

    热门问题