迭代创建列表嵌套:为何append()重复添加同一列表而非不同子列表
我想要创建一个嵌套列表,每个子列表依次递增1,预期结果是:
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
我写了下面的代码,但list_of_lists返回的却是重复10次的同一个列表:
list_of_lists = [] temporary = [] for i in range(1,11): temporary.append(i) print(temporary) # 打印temporary的时候是正常的:i=1时输出[1],i=2时输出[1,2] list_of_lists.append(temporary) print(list_of_lists) # 但list_of_lists里每次都是追加temporary的最新版本,最后所有元素都一样
我的理解是list_of_lists.append(temporary)应该把当前temporary的“快照”添加到末尾,但它却覆盖了之前添加的版本,不是在后面追加新的版本。我已经知道正确写法,但想搞懂我逻辑错在哪。
实际结果:
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
核心问题是Python中列表是可变对象,你append到list_of_lists里的不是列表的“副本”,而是指向同一个列表对象的引用。
你循环里的temporary自始至终都是同一个列表对象,每次append(i)只是修改这个对象的内容,而list_of_lists.append(temporary)只是把这个对象的引用重复添加了10次。所以当你最后查看list_of_lists时,所有元素都指向同一个已经被修改到最终状态的temporary列表,自然全是[1,2,...,10]。
你看到循环里打印temporary时是正确的,那是因为每次打印时这个对象的内容确实是当前的状态,但list_of_lists里存的不是当时的内容,而是指向这个对象的“指针”。后续修改temporary时,所有引用它的地方都会看到变化。
举个极简例子验证这个逻辑:
a = [] b = [a] a.append(1) print(b) # 输出[[1]],因为b里的元素是a的引用,a变了b也跟着变
你的逻辑错误在于误以为append会复制当前列表的内容并添加,实际上它只添加了对原对象的引用。如果要实现预期效果,每次循环都需要创建一个新的列表对象,比如:
list_of_lists = [] temporary = [] for i in range(1,11): temporary.append(i) list_of_lists.append(temporary.copy()) # 或者用list(temporary)、temporary[:]创建副本
这样每次添加的都是当前temporary的副本,是独立的新对象,后续修改temporary不会影响已经添加到list_of_lists里的元素。
内容的提问来源于stack exchange,提问作者Reddington

