2014-12-05 87 views
0

在此先感謝您的幫助。Python - 從一個文件讀取數據並選擇性寫入新文件

我是Python新手,正試圖將文件從一種格式轉換爲另一種格式。

這裏是我的代碼:

在頂部,隨後的數據線
fs = open('sample_data.txt','r') 
fnew = open('sample_output.txt','w') 
with fs as f: 
    while True: 
     line = f.readline() 
     if line and line[0]=='#': 
      print(line) 
      fnew.write(line + '\n') 
     else: 
      data=line.split() 
      fnew.write(data[0]) 
     if not line: break 

print('end of program') 
fs.close 
fnew.close 

文件的基本格式包含評論頭。

我遇到的問題是我的fnew.write(data [0])行。我得到以下錯誤:

IndexError:列表索引超出範圍

線分割​​打破了數據的八列,其中我想刪除了第2位。所以,最終,我想要做的是重寫整個文件減去前兩列。我需要做一些更復雜的重新格式化,但我希望如果我能理解這一步中的錯誤,我可以弄清楚如何完成剩下的工作。

--------------更新

abarnet,你說得對。這是導致錯誤的換行符。不過,如您所說,我在嘗試添加支票時遇到了另一個問題。當我執行下面的代碼時,一切都凍結在我身上。如果我刪除「如果數據:」檢查,然後運行,但給我相同的「索引超出範圍」的錯誤。

我也嘗試運行它,如下面的「如果數據:」檢查刪除,並與示例數據文件不包含換行符,它也凍結了我。

任何人都可以解釋什麼可能導致這種情況?

fs = open('sample_data.txt','r') 
fnew = open('sample_output.txt','w') 
with fs as f: 
    while True: 
     line = f.readline() 
     for line in f: 
      if line[0]=='#': 
       print(line) 
       fnew.write(line + '\n') 
      else: 
       data=line.split() 
       if data: 
        print(data[0]) 
        fnew.write(data[0] + '\n') 

print('end of program') 
fs.close 
fnew.close 

--------------更新2

此代碼下面的作品。感謝abarnet澄清無限循環問題。我遇到的最後一個問題是數據的第一行,無論是換行符還是標題行都會被忽略,並且不會輸出。

with open('sample_data.txt','r') as f, open('sample_output.txt','w') as fnew: 
    line = f.readline() 
    for line in f: 
     if line[0]=='#': 
      print(line) 
      fnew.write(line + '\n') 
     else: 
      data=line.split() 
      if data: 
       print(data[0]) 
       fnew.write(data[0] + '\n') 

print('end of program') 
fnew.close() 
+0

嘗試包故障fwrite的一個嘗試,除了在不同的塊體和打印數據,看看你有什麼 – Dinesh 2014-12-05 22:18:24

+0

呼叫打印您的數據變量嘗試寫之前。它輸出什麼? – 2014-12-05 22:22:30

+0

作爲一邊......你可以用下面的「for fs.readlines():」代替這三行「用fs作爲f:/ while True:/ line = f.readline()」。這不會解決你的問題,但它會讓你的代碼更好看(我的意思是更簡單)。 – 2014-12-06 03:32:36

回答

1

首先,如果line爲空會發生什麼?

您將最終到達if not line: break。但在你到達那裏之前,你會得到第一個else:(因爲它不是line and line[0]=='#')。所以,你的data = line.split()會給你data = []。然後data[0]將籌集IndexError

就先移動if not line: break測試:

while True: 
    line = f.readline() 
    if not line: 
     break 
    elif line[0]=='#': 
     print(line) 
     fnew.write(line + '\n') 
    else: 
     data=line.split() 
     fnew.write(data[0]) 

話雖這麼說,有擺在首位寫這更簡單的方法。循環遍歷一個文件會逐一給出每一行,如while環路readline,除了當它到達EOF時,循環自動結束,無需您測試任何東西或break

for line in f: 
    if line[0]=='#': 
     print(line) 
     fnew.write(line + '\n') 
    else: 
     data=line.split() 
     fnew.write(data[0]) 

但如果線空的,如果它只是一片空白,或者純粹的空白,會發生什麼?例如,在' \n'上致電split()會發生什麼情況?再次,你會得到一個空的列表。所以,如果可能的話,你會再次遇到同樣的問題 - 當然,在這種情況下,你可能不想要break。我不確定你想要做什麼,但假設你想跳過空白鏈接。因此,只需更換else塊與此:

data=line.split() 
if data: 
    fnew.write(data[0]) 

作爲一個側面說明,這是很奇怪的做fnew.write(line + '\n')在第一種情況下,當線已經處於\n端頭,這樣你只是添加額外的換行符,但隨後在其他情況下,如果data[0]不換行結束fnew.write(data[0]),所以你只是合併第一列的一起奔跑與上漲到年底的下一個評論一個巨大的字......


您的新代碼的問題是,代替替換while True:環路readline()for line in f:循環,您得到

所以,第一次通過while循環,它讀取第一行,然後讀取文件中的每一行,然後結束。然後,第二次通過while循環,它讀取最後剩下的部分,然後讀取剩餘的全部0行,然後結束。它會一直持續下去,直到最後一次讀完最後一行0,因爲你從來沒有breakwhile True:

您的更新代碼中還有一些其他問題。

  • fs.close只是引用的方法,而不實際調用它。您需要括號才能撥打電話,例如fs.close()
  • 不過你不想要fs.close(); with聲明的全部重點是它會自動關閉文件。
  • 您可能還想爲fnew使用with語句。

所以:

​​
+0

感謝您的幫助。我使用您推薦的更改更新了我的代碼。出於某種原因,當我嘗試執行代碼時,代碼凍結在我身上。 – DataCruncher 2014-12-08 17:58:07

+0

@DataCruncher:查看我更新的答案,解釋你做錯了什麼以及如何解決它。 – abarnert 2014-12-08 21:48:55

+0

感謝您澄清無限循環以及文件關閉。我更新了頂部的代碼。它按預期工作,但由於某些原因,它不打印文件的第一行。 – DataCruncher 2014-12-08 23:11:17

相關問題