在 Python 中动态填充字典

我有这个自制的模拟退火算法,用于计算具有N个点数的系统的最低能量。两点之间的能量计算为1 / r,其中a是两点之间的距离。我在循环中运行我的代码,一旦我离开循环,我就会更新字典中的新条目。问题是,在循环中的最后一次运行时,计算机似乎将最后一个条目保存为所有条目。请参阅下面的代码:


def energy_find(number,Ts=T_s,Tf=T_f):

    val_dic = {}

    c = 0 

    radius,theta = generate_random(number)

    energy,matrix = total_energy(number,radius,theta)

    val_dic[0] = []

    val_dic[0] = {"radius":radius,"theta":theta,"energy":energy,"energies":matrix}

    m = 5 # number of repetitions per given temperature

    for i in range(m):

        c +=1

        old_theta = val_dic[c-1]["theta"]

        old_radius = val_dic[c-1]["radius"]

        energy= val_dic[c-1]["energy"]

        old_energies = val_dic[c-1]["energies"]

        new_theta,new_radius,which = moveCharge(number,old_theta,old_radius)

        new_energy,enMatrix= recalculate(number,new_radius,new_theta,old_energies,which)

        delta_energy = new_energy-energy

        newset = [new_radius,new_theta,new_energy,enMatrix]

        val_dic = acceptChange(newset,delta_energy,val_dic,c,Ts)        

        print(val_dic[c]['radius'])

    df = pd.DataFrame(val_dic).T

    energy = df.energy.min()

    index =  pd.to_numeric(df.energy).idxmin()

    theta = df.loc[index,"theta"]

    radius = df.loc[index,"radius"]


    return df,energy,radius,theta,delta,val_dic

如您所见,上面有一个pring语句,可以正确打印点状电荷的径向位置如何变化。但是,一旦该函数运行:


df,energy,radius,theta,delta,dic= energy_find(5)

print("stop")

print(dic[1]["radius"])

输出为:


[3, 4.95, 6, 9, 2]

[5.05, 4.95, 6, 9, 2]

[3.0, 4.95, 6, 9, 2]

[3.0, 4.95, 6, 9, 4.05]

[5.05, 4.95, 6, 9, 4.05]

stop

[5.05, 4.95, 6, 9, 4.05]

为:


print(dic[2]["radius"]) 

输出:


[5.05, 4.95, 6, 9, 4.05]

没错,就像dic[1]一样,并且等于函数运行时for循环中打印的最后一个值。我是否错误地使用了字典?


慕姐8265434
浏览 111回答 1
1回答

桃花长相依

我认为问题是,当你写这样的东西时:old_theta = val_dic[c-1]["theta"]你没有复制你所做的前一个θ,old_theta引用同一个对象,如果你进一步改变old_theta它也会改变val_dic[c-1][“theta”]。您可以使用复制模块来避免此问题,并按如下方式更改行:import copy old_theta = copy.copy(val_dic[c-1]["theta"])old_radius = copy.copy(val_dic[c-1]["radius"])energy= copy.copy(val_dic[c-1]["energy"])old_energies = copy.copy(val_dic[c-1]["energies"])那么old_radius将只是前一个半径的值,而不是同一个对象
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python