为什么 mylist[:] = reversed(mylist) 有效?
Why does `mylist[:] = reversed(mylist)` work?
以下反转列表 "in-place" 并适用于 Python 2 和 3:
>>> mylist = [1, 2, 3, 4, 5]
>>> mylist[:] = reversed(mylist)
>>> mylist
[5, 4, 3, 2, 1]
Why/how?由于 reversed
给了我一个迭代器并且没有事先复制列表,并且由于 [:]=
替换了 "in-place",我很惊讶。以下内容也使用 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()
。
CPython 列表切片赋值将首先通过调用 PySequence_Fast
. Source: https://hg.python.org/cpython/file/7556df35b913/Objects/listobject.c#l611
将可迭代对象转换为列表
v_as_SF = PySequence_Fast(v, "can only assign an iterable");
甚至 PyPy 也做一些事情 similar:
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
will call ObjSpace.unpackiterable
解压可迭代对象 returns 一个列表。
以下反转列表 "in-place" 并适用于 Python 2 和 3:
>>> mylist = [1, 2, 3, 4, 5]
>>> mylist[:] = reversed(mylist)
>>> mylist
[5, 4, 3, 2, 1]
Why/how?由于 reversed
给了我一个迭代器并且没有事先复制列表,并且由于 [:]=
替换了 "in-place",我很惊讶。以下内容也使用 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()
。
CPython 列表切片赋值将首先通过调用 PySequence_Fast
. Source: https://hg.python.org/cpython/file/7556df35b913/Objects/listobject.c#l611
v_as_SF = PySequence_Fast(v, "can only assign an iterable");
甚至 PyPy 也做一些事情 similar:
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
will call ObjSpace.unpackiterable
解压可迭代对象 returns 一个列表。