Как отметил Марк Толонен в кратком комментарии, причина, по которой ваши попытки 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, но не зависает (я не проверял реализацию, чтобы выяснить, почему):
>>> 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)