在for循环中赋值之前引用的局部变量



我们必须读取轨迹xyz文件(py3dmol(,计算所有";相位";并将这些键长添加到列表中。当我试图用给定的文件执行它时,它会给我错误";赋值前引用的局部变量"c_line";。我想我理解问题是什么——我必须告诉循环继续使用它在语句中分配的变量,但我该如何解决它?我已经尝试将坐标赋值(c_x = etc(放在if语句中,但要么在o_xco_vector行中触发了相同的错误,要么函数不返回任何内容。

还是我做错了?我试过了我能想到的每一种变化,但我觉得我可能有精神障碍。

EDIT:我知道问题是什么。if语句只允许一次定义c_lineo_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

相关内容

最新更新