我们必须读取轨迹xyz文件(py3dmol(,计算所有";相位";并将这些键长添加到列表中。当我试图用给定的文件执行它时,它会给我错误";赋值前引用的局部变量"c_line";。我想我理解问题是什么——我必须告诉循环继续使用它在语句中分配的变量,但我该如何解决它?我已经尝试将坐标赋值(c_x = etc
(放在if语句中,但要么在o_x
的co_vector
行中触发了相同的错误,要么函数不返回任何内容。
还是我做错了?我试过了我能想到的每一种变化,但我觉得我可能有精神障碍。
EDIT:我知道问题是什么。if语句只允许一次定义c_line
或o_line
中的一个,而我需要为每个循环定义这两个来执行计算。但如果不通过if语句搜索,我不知道如何在文件中找到这些特定的行。(我希望这有道理(有什么想法可以绕过这个问题吗?在作业中,它说我们应该以某种方式使用if语句。
def co_bond(file):
file = open(file,'r') ## read file
lines = file.readlines()
file.close()
bond_list = []
c_x = 0
c_y = 0
c_z = 0
o_x = 0
o_y = 0
o_z = 0
for line in lines: # loop through entire file
if line.startswith("c"): # find c-atom lines
c_line = line.split()[1:] # have only coordinates (first item is atom name)
elif line.startswith("o"): # find o-atom lines
o_line = line.split()[1:]
c_x = float(c_line[0]) # create c-atom coordinates
c_y = float(c_line[1])
c_z = float(c_line[2])
o_x = float(o_line[0]) # create o-atom coordinates
o_y = float(o_line[1])
o_z = float(o_line[2])
co_vector = [o_x - c_x, o_y - c_y, o_z - c_z] # create vector between c and o
co_length = sqrt(co_vector[0]**2 + co_vector[1]**2 + co_vector[2]**2) # calculate bondlength
bond_list_filled = bond_list.append(co_length)
return bond_list_filled
试试这个:
if line.startswith("c"): # find c-atom lines
c_line = line.split()[1:] # have only coordinates (first item is atom name)
c_x = float(c_line[0]) # create c-atom coordinates
c_y = float(c_line[1])
c_z = float(c_line[2])
elif line.startswith("o"): # find o-atom lines
o_line = line.split()[1:]
o_x = float(o_line[0]) # create o-atom coordinates
o_y = float(o_line[1])
o_z = float(o_line[2])
问题是,当其中一行是o-atom时,您不定义c_line,而是在执行c_line[0]时使用它。因此,在给变量c_line赋值之前,先引用它。
好吧,我很愚蠢。在从头开始重写了几次代码后,我意识到我用原始答案尝试的一个版本是正确的。然而,让我不知所措的关键是:bond_list_filled = bond_list.append(co_length)
。在将其更改为仅bond_list.append(co_length)
之后,它运行得非常好。
这里有两个版本,适用于任何可能好奇的人:
(1( 一个与我最初发布的略有不同的版本
def co_bond(file):
file = open(file,'r') # read file
lines = file.readlines()
file.close()
bond_list = []
c_x = 0
c_y = 0
c_z = 0
o_x = 0
o_y = 0
o_z = 0
for line in lines: # loop through entire file
if line.startswith("c"): # find c lines
c_line = line.split()[1:]
c_x = float(c_line[0]) # create c coordinates
c_y = float(c_line[1])
c_z = float(c_line[2])
for line in lines:
if line.startswith("o"): # find o lines
o_line = line.split()[1:]
o_x = float(o_line[0]) # create o coordinates
o_y = float(o_line[1])
o_z = float(o_line[2])
co_vector = [o_x - c_x, o_y - c_y, o_z - c_z] # create vector
co_length = sqrt(co_vector[0]**2 + co_vector[1]**2 + co_vector[2]**2) # calculate length
bond_list.append(co_length)
return bond_list
(2( 我重写的东西:
def co_bond(file):
file = open(file,'r') # read file
lines = file.readlines()
file.close()
bond_list = []
c_line_list = []
o_line_list = []
for line in lines:
if line.startswith("c"): # find c lines
c_line = line.split()[1:]
c_line_list.append(c_line)
for line in lines:
if line.startswith("o"): # find c lines
o_line = line.split()[1:]
o_line_list.append(o_line)
for i in range(len(c_line_list)):
c_x = float(c_line_list[i][0]) # create c coordinates
c_y = float(c_line_list[i][1])
c_z = float(c_line_list[i][2])
o_x = float(o_line_list[i][0]) # create o coordinates
o_y = float(o_line_list[i][1])
o_z = float(o_line_list[i][2])
co_vector = [o_x - c_x, o_y - c_y, o_z - c_z] # create vector
co_length = sqrt(co_vector[0]**2 + co_vector[1]**2 + co_vector[2]**2) # calculate length
bond_list.append(co_length)
return bond_list