Python函数返回每行值重复的多维数组问题排查求助
问题排查:列表元素被重复覆盖的原因
我写了一个函数,针对SCounts中的每个元素,以FS数组为权重在0-10范围内采样对应次数,再重新分箱到0-10区间(这部分功能正常)。实际场景中channelNumbers和SCounts的长度会更大。现在遇到的问题是:循环内部打印每行值都不同(符合预期),但循环外所有行都被最后一行数组覆盖,求原因。
代码示例
import random from collections import Counter import numpy as np FS = [7.23900537e+01, 3.20399585e+02, 7.87859277e+01, 7.13517144e+02, 3.65143642e+02, 2.13185063e+02, 2.14225579e+02, 2.00109435e+02, 1.80659967e+02, 1.63896939e+02] SCounts = [5277.872472199431, 5646.015740911809, 4864.201935526552, 5258.38505381198, 3850.1494907432266] channelNumbers = 10 def Samp(SCounts,FS): tot = np.sum(FS) channels = range(channelNumbers) spectra = [[0]*channelNumbers]*len(SCounts) for n in range(len(SCounts)): #n-loop values = random.choices(channels, weights = FS/tot,k=round(SCounts[n])) #Count the number of times a channel number occurs counter = Counter(values) #Fill list per channel with the number of counts for i in range(channelNumbers): spectra[n][i] = counter.get(i+1) print(spectra[n]) print("Outside n-loop:") print(spectra[0]) print(spectra[4]) return spectra spectra = Samp(SCounts,FS)
运行输出
[693, 167, 1469, 754, 446, 455, 426, 375, 346, None] [678, 167, 1663, 803, 519, 464, 427, 398, 375, None] [581, 134, 1376, 757, 383, 451, 359, 355, 309, None] [667, 159, 1491, 757, 425, 473, 399, 397, 335, None] [494, 123, 1052, 569, 339, 308, 295, 266, 275, None] Outside n loop: [494, 123, 1052, 569, 339, 308, 295, 266, 275, None] [494, 123, 1052, 569, 339, 308, 295, 266, 275, None]
问题原因
问题出在这行代码:
spectra = [[0]*channelNumbers]*len(SCounts)
用[x]*n的方式创建嵌套列表时,所有子列表都是同一个列表对象的引用。也就是说,spectra[0]、spectra[1]...spectra[4]指向的是同一个内存地址的列表。每次循环修改spectra[n][i]时,其实都是在修改同一个底层列表,最后所有行都会被最后一次循环的修改覆盖。
修复方案
把嵌套列表的创建方式改成每次生成新的子列表,避免引用复用:
spectra = [[0]*channelNumbers for _ in range(len(SCounts))]
或者用numpy直接初始化数组(如果后续用numpy操作更方便):
spectra = np.zeros((len(SCounts), channelNumbers), dtype=int)
修改后,每个子列表都是独立的对象,循环中修改各自的元素不会互相影响。
内容的提问来源于stack exchange,提问作者Cv33
相关产品推荐
相关产品推荐

