我试图在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")
答案 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)
但是,我同意其他人的观点,并且我会尝试使用不同的方法解决您尝试解决的问题,而不是从文件中不断删除单行。我上面概述的解决方案效率很低。