有人可以通过易于理解的方式解释修改与覆盖对象引用吗?这是我的意思的一个例子:
修改对象引用:
nested_list = [[]]*3
nested
result:
[[], [], []]
# now let me **modify** the object reference
nested[1].append('zzz')
result:
[['zzz'], ['zzz'], ['zzz']]
通过覆盖对象引用:
nested_list = [[]]*3
nested
result:
[[], [], []]
# now let me **modify** the object reference
nested[1] = ['zzz']
result:
[[], ['zzz'], []]
这是否意味着在使用"追加"我们只是在使用赋值时修改对象引用,即
nested[1] = ['zzz']
我们是否覆盖了值并将嵌套[1]赋值给新的对象引用?是否由"追加"之间的潜在差异引起?方法和赋值?如果是这样的差异是什么?
答案 0 :(得分:2)
让我们将名称x
分配给一个空列表,以便更容易推理代码。
在你的第一个例子中
>>> x = []
>>> nested = [x]*3
>>> nested
[[], [], []]
您正在创建一个列表nested
,其中包含对x
的三个引用。这是证据:
>>> all(e is x for e in nested)
True
我们只创建了一个空列表x
,这就是
nested[0].append('zzz')
nested[1].append('zzz')
nested[2].append('zzz')
和
x.append('zzz')
都是等效的,并将附加到内存中的相同列表:
>>> nested[0].append('zzz')
>>> nested
[['zzz'], ['zzz'], ['zzz']]
>>> nested[1].append('zzz')
>>> nested
[['zzz', 'zzz'], ['zzz', 'zzz'], ['zzz', 'zzz']]
>>> nested[2].append('zzz')
>>> nested
[['zzz', 'zzz', 'zzz'], ['zzz', 'zzz', 'zzz'], ['zzz', 'zzz', 'zzz']]
>>> x.append('zzz')
>>> nested
[['zzz', 'zzz', 'zzz', 'zzz'], ['zzz', 'zzz', 'zzz', 'zzz'], ['zzz', 'zzz', 'zzz', 'zzz']]
第二个例子很简单。您创建一个列表nested
,该列表最初包含对同一空列表的三个引用。
然后你覆盖 nested
的第二个元素(即nested[1]
)通过发布
>>> x = []
>>> nested = [x]*3
>>> nested[1] = ['zzz']
>>> nested
[[], ['zzz'], []]
nested
的第二个元素是一个与nested
的第一个和第三个元素无关的新列表。
>>> nested[0] is nested[1]
False
>>> nested[2] is nested[1]
False
>>> nested[0] is nested[2]
True
由于您没有修改nested[0]
和nested[2]
引用,因此它们仍然保持相同的空列表(在我们的示例中也使用名称x
)。
>>> x.append('x')
>>> nested
[['x'], ['zzz'], ['x']]
答案 1 :(得分:1)
正如我在评论中写的那样,*
上的list
运算符只是复制了列表中的引用:
nested_list = [[]] * 3
nested_list
内的所有三个元素都指向同一个列表。如果您考虑上面的表达式真正说出的内容,这是有道理的。评估确实按以下顺序进行:
nested_list = [[]] # first create a list with an empty list.
nested_list = nested_list * 3 # duplicate the references to that empty list
到你问题的第二部分。如果用新列表替换第二个元素:
nested_list[1] = ['zzz']
第一个和第三个元素引用相同的空列表,但刚刚分配给(['zzz']
)的元素是一个新列表(带有一个元素'zzz'
。)
E.g。如果您执行以下操作,您将看到第一个和第三个仍然引用相同的列表:
nested_list[0].append('a')
print(nested_list)
# [['a'], ['zzz'], ['a']]
要创建三个不同的空列表,这可能是您想要的,您通常会执行类似的操作(以下行是等效的):
nested_lists = [[] for _ in range(3)]
nested_lists = [[], [], []]