读取具有可变列的文件

问题描述:

我试图在xyz文件中读入python,但不断收到这些错误消息。有点新的Python,所以会喜欢一些帮助解释它!读取具有可变列的文件

def main(): 
    atoms = [] 
    coordinates = [] 
    name = input("Enter filename: ") 
    xyz = open(name, 'r') 
    n_atoms = xyz.readline() 
    title = xyz.readline() 
    for line in xyz: 
     atom, x, y, z = line.split() 
     atoms.append(atom) 
     coordinates.append([float(x), float(y), float(z)]) 
    xyz.close() 

    return atoms, coordinates 


if __name__ == '__main__': 
    main() 

Error: 
Traceback (most recent call last): 
    File "Project1.py", line 25, in <module> 
    main() 
    File "Project1.py", line 16, in main 
    atom, x, y, z = line.split() 
ValueError: not enough values to unpack (expected 4, got 3) 

我认为值误差是因为几行后,只有3个值。但不知道为什么我得到返回错误。

一个非常重要的经验法则,特别是在python中是:不要重新发明*并使用现有的库。

xyz文件是化学中少数普遍使用的文件格式之一。所以恕我直言,你不需要任何逻辑来确定你的线的长度。第一行是一个整数n_atoms并给出了原子数,第二行是一个被忽略的注释行,下一个n_atoms行是[string, float, float, float],因为您已经写入了代码。与此不同的文件可能已损坏。

使用pandas library可以简单的写:

import pandas as pd 
molecule = pd.read_table(inputfile, skiprows=2, delim_whitespace=True, 
         names=['atom', 'x', 'y', 'z']) 

或者你使用chemcoord包,其中有代表在直角坐标系的分子自身的笛卡尔类:

import chemcoord as cc 
molecule = cc.Cartesian.read_xyz(inputfile) 

免责声明:我是作者chemcoord。

+0

非常感谢!我一定会在未来考察图书馆! – Camerann

,因为你在该行

atom, x, y, z = line.split() 

时才有意义解包的列表,如果有该行4项你得到的错误。

你必须定义的时候只有3个在行项目,像这样(在for环路内)会发生什么逻辑:

for line in xyz: 
    line_data = line.split() 
    if len(line_data) == 3: 
     # Behavior when only 3 items in a line goes here! 
     # Add your code here! 
     continue 

    atom, x, y, z = line_data 
    atoms.append(atom) 
    coordinates.append([float(x), float(y), float(z)]) 

时遇到行只有3你的程序在做什么项目取决于你想要的东西。

+0

它可能也会检查'len(line_data)== 4'情况 –

+0

@ cricket_007 =='4情况已经实现。如果长度既不是3也不是4,程序将(正确)崩溃,从而提醒程序员必须为新格式(例如5项)添加代码。 – phihag

+0

我会将这个列表只解压到4个项目'如果len(line_data)== 4'。否则报告意外的格式“len(line_data)!= 4”。我觉得奇怪只有意想不到的3格式,并让5,6,7,8等程序崩溃... – JoonasS