2014-12-05 67 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

相关问题