You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3循环中向列表追加元素异常问题求助

问题描述

我在Python3中迭代向列表添加元素时遇到困难,以下是最小可复现示例(MWE):

# Given a nested list of values, or sets
sets = [[1, 2, 3], [1, 2, 4], [1, 2, 5]]
    
# add a value to each sublist giving the number of that set in the list.
n_sets = len(sets)
for s in range(n_sets):
    (sets[s]).insert(0, s)

# Now repeat those sets reps times
reps = 4
expanded_sets = [item for item in sets for i in range(reps)]

# then assign a repetition number to each occurance of a set.
rep_list = list(range(reps)) * n_sets
for i in range(n_sets * reps):
    (expanded_sets[i]).insert(0, rep_list[i])
    
expanded_sets

执行后得到的实际输出不符合预期:

[[3, 2, 1, 0, 0, 1, 2, 3],
 [3, 2, 1, 0, 0, 1, 2, 3],
 [3, 2, 1, 0, 0, 1, 2, 3],
 [3, 2, 1, 0, 0, 1, 2, 3],
 [3, 2, 1, 0, 1, 1, 2, 4],
 [3, 2, 1, 0, 1, 1, 2, 4],
 [3, 2, 1, 0, 1, 1, 2, 4],
 [3, 2, 1, 0, 1, 1, 2, 4],
 [3, 2, 1, 0, 2, 1, 2, 5],
 [3, 2, 1, 0, 2, 1, 2, 5],
 [3, 2, 1, 0, 2, 1, 2, 5],
 [3, 2, 1, 0, 2, 1, 2, 5]]

期望输出为:

[[0, 0, 1, 2, 3],
 [1, 0, 1, 2, 3],
 [2, 0, 1, 2, 3],
 [3, 0, 1, 2, 3],
 [0, 1, 1, 2, 4],
 [1, 1, 1, 2, 4],
 [2, 1, 1, 2, 4],
 [3, 1, 1, 2, 4],
 [0, 2, 1, 2, 5],
 [1, 2, 1, 2, 5],
 [2, 2, 1, 2, 5],
 [3, 2, 1, 2, 5]]

第一个循环后sets得到预期值,但第二个循环后原列表sets被意外修改,怀疑和列表的引用与拷贝有关,尝试过添加.copy()和切片操作,修改rep_list生成方式也未解决问题,使用Python 3.10.6版本,寻求解决办法。

问题原因

核心问题是列表的引用传递:

  • 生成expanded_sets时,列表推导式[item for item in sets for i in range(reps)]中的item是原sets中子列表的直接引用,而非独立拷贝。
  • 因此expanded_sets中同一组的4个元素都指向同一个原列表对象,每次对expanded_sets[i]执行insert操作,都会修改同一个底层列表,导致多次插入的内容叠加。
  • 同时,修改expanded_sets中的元素也会同步修改原sets中的子列表,因为它们指向同一个对象。
解决方法

在生成expanded_sets时,对每个子列表做浅拷贝,确保每个元素都是独立的新列表。可以用item.copy()或者切片item[:]实现:

修正后的代码:

sets = [[1, 2, 3], [1, 2, 4], [1, 2, 5]]
    
n_sets = len(sets)
for s in range(n_sets):
    sets[s].insert(0, s)

reps = 4
# 这里添加.copy()生成独立拷贝
expanded_sets = [item.copy() for item in sets for i in range(reps)]

rep_list = list(range(reps)) * n_sets
for i in range(n_sets * reps):
    expanded_sets[i].insert(0, rep_list[i])
    
print(expanded_sets)

执行后即可得到期望输出:

[[0, 0, 1, 2, 3],
 [1, 0, 1, 2, 3],
 [2, 0, 1, 2, 3],
 [3, 0, 1, 2, 3],
 [0, 1, 1, 2, 4],
 [1, 1, 1, 2, 4],
 [2, 1, 1, 2, 4],
 [3, 1, 1, 2, 4],
 [0, 2, 1, 2, 5],
 [1, 2, 1, 2, 5],
 [2, 2, 1, 2, 5],
 [3, 2, 1, 2, 5]]

补充说明

如果子列表中还包含嵌套的可变对象(比如更深层的列表),则需要使用copy.deepcopy()进行深拷贝,但本案例中仅需浅拷贝即可解决问题。

内容的提问来源于stack exchange,提问作者zazizoma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 00:01:15