为何参数output_wavelets值变化?如何保留原始字典?
这是Python中可变对象引用传递的典型表现:
在Python里,字典(dict)属于可变容器类型。当你把output_wavelets作为参数传入graphwave函数时,传递的并不是字典的完整副本,而是指向这个字典对象的内存引用。也就是说,graphwave函数里操作的output_wavelets和getGraphWave里的原始字典是同一个对象。
所以第一次调用graphwave(10, output_wavelets)时,函数内部通过output_wavelets.pop(Seed)移除了10个键值对,直接修改了原始字典。等第二次调用graphwave(20, output_wavelets)时,字典已经是被修改后的状态(长度变为2000-10=1990,和你看到的1991属于示例中的近似值)。
要让output_wavelets始终保持原始状态,核心思路是每次调用graphwave时,传入原始字典的副本而非原对象本身。根据你的场景,有两种简单可行的实现方式:
方式1:在调用时传入副本
修改getGraphWave函数中的循环逻辑,每次调用graphwave时创建并传入原始字典的浅拷贝:
def getGraphWave(G, d, maxk, p): data = dict() output_wavelets = {2:33,5:77,...} # 原始长度2000的字典 print(len(output_wavelets)) k = [10,20] for i in k: # 传入原始字典的浅拷贝,避免修改原对象 S = graphwave(i, output_wavelets.copy()) size = IC(d, S, p) data[i] = size + i return data
因为你的字典值是数字(不可变类型),浅拷贝(copy()方法)完全足够。如果字典值包含可变类型(比如列表),则需要用copy.deepcopy()来创建深拷贝。
方式2:在graphwave内部使用副本
如果你不想修改调用处的代码,也可以在graphwave函数内部先创建原始字典的副本,后续操作都基于副本进行:
def graphwave(k, output_wavelets): # 先创建原始字典的副本,操作副本而非原对象 wavelet_copy = output_wavelets.copy() S = [] print(len(wavelet_copy)) # 每次都会打印2000 for i in range(k): Seed = max(wavelet_copy, key=wavelet_copy.get) S.append(Seed) wavelet_copy.pop(Seed) return S
这种方式对调用方更友好,不需要额外修改getGraphWave的逻辑,就能保证原始字典始终不受影响。
内容的提问来源于stack exchange,提问作者Z Mario

