2017-06-12 55 views
2

我試圖在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個值。但不知道爲什麼我得到返回錯誤。

回答

2

一個非常重要的經驗法則,特別是在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

0

,因爲你在該行

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