正如 Mark Tolonen 在简明评论中指出的那样,您的 itertools 尝试无限期循环的原因是,对于列表分配,python 正在检查右侧的长度。
现在要真正深入...
当你说:
x[::2] = itertools.repeat(False)
左侧 ( x[::2]
) 是一个列表,您正在为一个列表分配一个值,其中该值是可迭代的,由于没有给出长度(根据文档)itertools.repeat(False)
,它将永远迭代。
如果您深入研究 cPython 实现中的列表分配代码,您会发现不幸/痛苦命名的函数list_ass_slice
,它是许多列表分配内容的根源。在该代码中,您将看到此段:
v_as_SF = PySequence_Fast(v, "can only assign an iterable");
if(v_as_SF == NULL)
goto Error;
n = PySequence_Fast_GET_SIZE(v_as_SF);
在这里,它试图获取n
您分配给列表的可迭代对象的长度 ()。但是,甚至在到达那里之前它就卡在了PySequence_Fast
,它最终尝试将您的可迭代对象转换为列表(使用PySequence_List
),最终在其中创建一个空列表并尝试使用您的可迭代对象简单地扩展它。
要使用可迭代扩展列表,它使用listextend()
,您将在其中看到问题的根源:
/* Run iterator to exhaustion. */
for (;;) {
你去吧。
或者至少我是这么认为的...... :) 这是一个有趣的问题,所以我想我会找点乐子并挖掘源代码以查看发生了什么,并最终到达那里。
至于 numpy 数组的不同行为,这只是numpy.array
分配处理方式的不同。
请注意,itertools.repeat
在 numpy 中 using 不起作用,但它不会挂断(我没有检查实现以找出原因):
>>> import numpy, itertools
>>> x = numpy.ones(10,dtype='bool')
>>> x[::2] = itertools.repeat(False)
>>> x
array([ True, True, True, True, True, True, True, True, True, True], dtype=bool)
>>> #but the scalar assignment does work as advertised...
>>> x = numpy.ones(10,dtype='bool')
>>> x[::2] = False
>>> x
array([False, True, False, True, False, True, False, True, False, True], dtype=bool)