阅读后删除一行

时间:2016-03-02 16:27:07

标签: python file

我试图在python中读取它之后删除一行。

with open("pages_Romance") as f:
   for line in f:
      print "Page: " + line
      #Do something with the line
      delete_a_line("pages_Romance", line)

我的函数delete_a_line实现如下:

def delete_a_line(path_file, line):
    with open(path_file, "r") as f:
       urls = f.readlines()
       if len(urls) == 1:
          print "File " + path_file + " deleted"
          os.remove(path_file)
       else:
          with open(path_file, "w") as f:
             for url in urls:
                if url != line:
                    f.write(url)
                else:
                    print url

我的文件pages_Romance包含200个URL(逐行),每次我读取一个我要删除的URL。问题是我每次启动脚本时都会在同一个地方遇到同样的问题,我的文件中的URL号为163,然后脚本停止。如果我减少了163个URL,但如果我有163个或更多URL,我会得到以下输出:

Page: http://www.allocine.fr/films/genre-130

然后脚本停止。我应该:

Page: http://www.allocine.fr/films/genre-13024/?page=163

我们可以帮助我解决这个问题。如果您希望可以尝试此脚本,它将创建包含200个URL的文件:

def create_url_file():
    with open("pages_Romance", "w") as f:
        for i in range(1,201):
            f.write("http://www.allocine.fr/films/genre-13024/?page=" + str(i) + "\n")

3 个答案:

答案 0 :(得分:3)

从磁盘上存储的文件中删除一行并不容易。大多数解决方案 - 就像你的尝试一样 - 实际上涉及将整个文件读入内存(逐行或全部一次),然后将所有文件全部写回磁盘,除了要删除的行。

因此,更自然的方法是在迭代和处理行的同时将要保留的行写入新文件。然后,您可以删除旧文件,并根据需要将其替换为新文件。这样可以避免将整个文件读入内存。

with open("pages_Romance") as in_file, open("pages_Romance_temp", "w") as out_file:
   for line in in_file:
      print "Page: " + line
      #Do something with the line
      if delete_this_line == False:
          out_file.write(line)

但是如果您的文件很短,请考虑将其全部读入内存并将其作为一个行数组处理,这可能会简化您的其他代码。

with open("pages_Romance") as f:
    urls = f.readlines()

# Do stuff with urls
urls.remove(unwanted_line)
# etc.

with open("pages_Romance", "w") as f:
    f.writelines(urls)

答案 1 :(得分:2)

我怀疑你正在迭代你正在改变的文件。外部循环打开文件,内部循环改变文件的长度。尝试仅从顶级函数迭代。

答案 2 :(得分:1)

虽然我不知道为什么它在为163行工作后会中断,但可能是因为您在delete_a_line中的文件仍在原始with块中仍处于打开状态时进行了更改。我可以通过在调用delete_a_line之前在每个外部迭代中打开和关闭文件来使其工作,因此文件永远不会在两个地方同时打开:

f = open("pages_Romance")
while f:
    line = f.readline()
    print "Page: " + line
    #Do something with the line
    f.close()
    delete_a_line("pages_Romance", line)
    try:
        f = open("pages_Romance")
    except IOError:
        f = None

此外,如果文件为空,delete_a_line无法删除文件本身,因为它仍处于打开状态(您尝试将其从with块中删除)。快速解决方法是设置一个标志,然后删除with块外的文件:

def delete_a_line(path_file, line):
    delete_flag = False
    with open(path_file, "r") as f:
        urls = f.readlines()
        if len(urls) == 1:
            delete_flag = True
        else:
            with open(path_file, "w") as f:
                for url in urls:
                    if url != line:
                        f.write(url)
                    else:
                        print url
    if delete_flag:
        print "File " + path_file + " deleted"
        os.remove(path_file)

但是,我同意其他人的观点,并且我会尝试使用不同的方法解决您尝试解决的问题,而不是从文件中不断删除单行。我上面概述的解决方案效率很低。