Python迭代添加列表至另一列表输出异常:问题排查
问题:迭代添加列表到另一个列表时,所有元素被最后一次迭代内容覆盖
迭代生成帕斯卡三角的每一行并添加到总列表中,最终总列表里的所有元素都是最后一行的内容,而非各行对应的帕斯卡三角值。
原代码
def pascal(n): """ print pascal triangle """ list = [] if (n > 0): lst = [] for line in range(1, n + 1): k = 1 lst.clear() for i in range(1, line + 1): lst.append(k) k = int(k * (line - i)/i) print(lst) list.append(lst) print (list) else: print (list) pascal(5)
实际输出
[1] [1, 1] [1, 2, 1] [1, 3, 3, 1] [1, 4, 6, 4, 1] [[1, 4, 6, 4, 1], [1, 4, 6, 4, 1], [1, 4, 6, 4, 1], [1, 4, 6, 4, 1], [1, 4, 6, 4, 1]]
期望输出
[1] [1, 1] [1, 2, 1] [1, 3, 3, 1] [1, 4, 6, 4, 1] [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
问题根源
Python中的列表是可变对象,你始终在复用同一个lst对象:每次调用lst.clear()只是清空该列表的内容,而非创建新列表;list.append(lst)添加的是lst的引用,不是当前内容的副本。因此总列表里的所有元素最终都指向同一个lst对象,显示的自然是最后一次修改后的内容。
解决方案
有两种常见的修复方式:
方式1:每次循环创建新列表
不再复用同一个lst,而是在每轮循环中新建列表,避免引用重复:
def pascal(n): """ print pascal triangle """ result_list = [] # 避免使用内置类型名`list`作为变量名 if n > 0: for line in range(1, n + 1): lst = [] # 每轮循环新建列表 k = 1 for i in range(1, line + 1): lst.append(k) k = int(k * (line - i)/i) print(lst) result_list.append(lst) print(result_list) else: print(result_list) pascal(5)
方式2:添加列表的副本而非引用
如果要保留复用lst的逻辑,在添加到总列表时,传入当前lst的副本(而非原对象的引用):
def pascal(n): """ print pascal triangle """ result_list = [] if n > 0: lst = [] for line in range(1, n + 1): k = 1 lst.clear() for i in range(1, line + 1): lst.append(k) k = int(k * (line - i)/i) print(lst) result_list.append(lst.copy()) # 添加副本,而非原列表引用 print(result_list) else: print(result_list) pascal(5)
两种方式都能让总列表正确保存每一行的帕斯卡三角值,得到期望的输出。
内容的提问来源于stack exchange,提问作者tola
相关产品推荐
相关产品推荐

