iz_*_*iz_ 5 python iterator list python-itertools python-3.x
可能是重复的,但我找不到任何东西。
\n\n我有一个很长的迭代器(10000 个项目),我需要一次迭代约 500 个项目。所以如果我的迭代器是range(10000),它看起来像这样:
Iteration #1: 0, 1, 2, ... 497, 498, 499\nIteration #2: 1, 2, 3, ... 498, 499, 500\nIteration #3: 2, 3, 4, ... 499, 500, 501\nIteration #4: 3, 4, 5, ... 500, 501, 502\n...\nIteration #9500: 9499, 9500, 9501 ... 9996, 9997, 9998\nIteration #9501: 9500, 9501, 9502 ... 9997, 9998, 9999\nRun Code Online (Sandbox Code Playgroud)\n\n等等。有这样一个方法:
\n\ndef nwise_slice(lst, n):\n for i in range(len(lst) - n + 1):\n yield lst[i:i + n]\nRun Code Online (Sandbox Code Playgroud)\n\n但是,这不适用于惰性迭代器。我尝试使用迭代器创建一个解决方案,并根据itertools pairwise和consume食谱(请参阅此处)进行改编来创建此解决方案:
import itertools\n\ndef nwise_iter(lst, n):\n iters = itertools.tee(lst, n)\n for idx, itr in enumerate(iters):\n next(itertools.islice(itr, idx, idx), None)\n\n for group in zip(*iters):\n yield group\nRun Code Online (Sandbox Code Playgroud)\n\n其作用相同(尽管产生 atuple而不是 a list,这对我来说并不重要)。我还相信它不会创建很多不必要的切片。该解决方案适用于不可切片的迭代器,例如文件(我计划使用它)。然而,该itertools解决方案速度慢了 2 倍:
In [4]: %timeit list(nwise_slice(list(range(10000)), 500))\n46.9 ms \xc2\xb1 729 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n\nIn [5]: %timeit list(nwise_iter(list(range(10000)), 500))\n102 ms \xc2\xb1 3.95 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\nRun Code Online (Sandbox Code Playgroud)\n\n我不想将所有测试数据加载到内存中才能利用该slice方法。有没有更有效的方法来实现这一目标?
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
624 次 |
| 最近记录: |