将迭代器分配给 Python 切片

Ole*_*hyn 6 python iterator slice

在 Python 中分配给切片之前是否消耗了迭代器?通过“在分配之前消耗”我的意思是在切片分配发生之前,所有元素都在内存中同时创建(放入列表或元组中)。另一种方法是将迭代器中的元素一个一个地放入切片中,因此不会同时在内存中创建元素。

例如,让我们考虑以下代码:

from itertools import islice
from heapq import merge

c = [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5] + list(range(10))
lo, mid, hi = 0, 10, 20
c[lo:hi] = merge(islice(iter(c), lo, mid), islice(iter(c), mid, hi))
Run Code Online (Sandbox Code Playgroud)

merge 返回一个迭代器,该迭代器选择给定合并的两个迭代器中的最小元素。这些迭代器会在切片分配发生之前被消耗吗?

use*_*ica 4

这取决于切片分配到的序列的实现。序列直接接收迭代器,消费迭代器的细节由序列决定。

对于列表,当前的 CPython 实现在对列表进行任何修改之前预先使用迭代器:

v_as_SF = PySequence_Fast(v, "can only assign an iterable");
Run Code Online (Sandbox Code Playgroud)

PySequence_Fast将从任何还不是列表或元组的参数中构建一个列表。

还有自分配处理,因为当您将列表切片分配给自身时,将输入转换为列表还不够安全:

/* Special case "a[i:j] = a" -- copy b first */
v = list_slice(b, 0, Py_SIZE(b));
Run Code Online (Sandbox Code Playgroud)

我认为此列表中的任何行为都没有记录。