(又一个)列出别名难题

Joe*_*ett 4 python

我以为我找到了整个列表别名的东西,但后来我发现了这个:

    l = [1, 2, 3, 4]
    for i in l:
        i = 0
    print(l)
Run Code Online (Sandbox Code Playgroud)

这导致:

    [1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.

但是,当我尝试这个时:

    l = [[1, 2], [3, 4], [5, 6]]
    for i in l:
        i[0] = 0
Run Code Online (Sandbox Code Playgroud)

我明白了

    [[0, 2], [0, 4], [0, 5]]
Run Code Online (Sandbox Code Playgroud)

为什么是这样?

这与锯齿的深度有关吗?

Ign*_*ams 8

第一个重新命名.重新绑定名称仅更改本地名称.第二个变异对象.变异对象会在引用它的任何地方改变它(因为它始终是同一个对象).


wim*_*wim 6

i = 0与...非常不同i[0] = 0.

伊格纳西奥已经简明扼要地解释了原因.所以我只想用一个更简单的词来解释这里究竟发生了什么.

在第一种情况下,i只是一个指向某个对象的标签(列表中的一个成员). i = 0更改对其他对象的引用,以便i现在引用整数0.该列表未经修改,因为您从未要求修改l[0]或任何元素l,您只需修改i.

在第二种情况下,i也只是指向列表中某个成员的名称.那部分也不例外.但是,i[0]现在正在调用.__getitem__(0)其中一个列表成员.同样,i[0] = 'other'就像在做i.__setitem__(0, 'other').它不是简单地指向i不同的对象,因为正则赋值语句会实际上它正在改变对象i.

想到它的简单方法总是Python中的名称只是对象的标签.作用域或命名空间就像将dict映射到对象的dict.

  • @Joel:`i`从未编入索引.对象`i`*绑定*被索引. (2认同)
  • @Joel:不是'i`被区别对待,但是`i [0] = 0`是与`i = 0`不同的操作.第一个只是让`i`成为`0`的名字.第二个是第0个插槽,无论什么`i`当前是引用'0`的名字.如果`i`绑定到一个数字,`i [0] = 0`将具有相同的效果,除了数字不包含任何"槽",因此操作会引发错误. (2认同)