Hei*_*erg 6 python reference list
我知道切片列表不会生成列表中对象的副本;它只是复制对它们的引用。
但如果是这样的话,那为什么这行不通呢?
l = [1, 2, 3]
# Attempting to modify the element at index 1
l[0:2][-1] = 10
# but the attempt fails. The original list is unchanged
l
> [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
不应该l[0:2][-1]
指向原始列表索引 1 处的元素吗?
您是对的,切片不会复制列表中的项目。但是,它确实创建了一个新的列表对象。
您的评论表明存在误解:
# Attempting to modify the element at index 1
l[0:2][-1] = 10
Run Code Online (Sandbox Code Playgroud)
这不是对元素的修改,而是对列表的修改。换句话说,它实际上是“更改列表,使索引 1 现在指向数字 10”。由于您的切片创建了一个新列表,因此您只需更改该新列表以指向其他某个对象即可。
在您对 oldrinb 的回答的评论中,您说:
为什么
l[0:1]
和l[0:1][0]
不同?它们不应该引用同一个对象,即 的第一项吗l
?
除了它l[0:1]
是一个列表而它l[0:1][0]
是一个元素之外,这里又存在同样的误解。假设这some_list
是一个列表,索引处的对象ix
是obj
。这:
some_list[ix] = blah
Run Code Online (Sandbox Code Playgroud)
。。。是对 的操作some_list
。对象obj
不涉及。这可能会令人困惑,因为这意味着some_list[ix]
根据其位于分配的哪一侧,语义略有不同。如果你这样做
blah = some_list[ix] + 2
Run Code Online (Sandbox Code Playgroud)
。。.那么您确实正在操作列表内的对象(即,它与 相同obj + 2
)。但是,当索引操作位于赋值的左侧时,它不再涉及所包含的对象,而只涉及列表本身。
当您分配给列表索引时,您正在修改列表,而不是其中的对象。所以在你的例子中l[0]
与 相同l[0:2][0]
,但这并不重要;因为您的索引是一个分配目标,所以它正在修改列表并且不关心其中已经有什么对象。