Подтвердить что ты не робот

Почему работает `mylist [:] = reverse (mylist)`?

Следующее отменяет список "на месте" и работает в Python 2 и 3:

>>> mylist = [1, 2, 3, 4, 5]
>>> mylist[:] = reversed(mylist)
>>> mylist
[5, 4, 3, 2, 1]

Почему/как? Поскольку reversed дает мне итератор и не скопирует список заранее, и поскольку [:]= заменяет "на месте", я удивлен. И следующее, также используя reversed, ломается, как ожидалось:

>>> mylist = [1, 2, 3, 4, 5]
>>> for i, item in enumerate(reversed(mylist)):
        mylist[i] = item
>>> mylist
[5, 4, 3, 4, 5]

Почему не работает [:] =?

И да, я знаю mylist.reverse().

4b9b3361

Ответ 1

Assignment slipt списка CPython сначала преобразует итерабельность в список, вызывая PySequence_Fast. Источник: https://hg.python.org/cpython/file/7556df35b913/Objects/listobject.c#l611

 v_as_SF = PySequence_Fast(v, "can only assign an iterable");

Даже PyPy делает что-то похожее:

def setslice__List_ANY_ANY_ANY(space, w_list, w_start, w_stop, w_iterable):
    length = w_list.length()
    start, stop = normalize_simple_slice(space, length, w_start, w_stop)
    sequence_w = space.listview(w_iterable)
    w_other = W_ListObject(space, sequence_w)
    w_list.setslice(start, 1, stop-start, w_other)

Здесь space.listview вызывается ObjSpace.unpackiterable для распаковки итерации, которая, в свою очередь, возвращает список.