处理后从文件中删除行

时间:2014-12-01 05:37:07

标签: python file

我正在逐行阅读文件中的内容。一旦线处理,我清除它。这是代码

import os
lines = open('q0.txt').readlines()

for i, line in enumerate(lines[:]):
    print line
    flag = raw_input()
    print lines[i]
    del lines[i]

open('q0.txt', 'w').writelines(lines)

我要经历大型q0.txt。我的意思是,如果介于两者之间有任何介入,我不应该再次处理先前处理过的行。

在上面的代码中,虽然我删除了lines[i],但它仍然保留在文件中。有什么问题?

2 个答案:

答案 0 :(得分:2)

我希望上面的代码在某个地方抛出IndexError

为什么呢?我们假设您的脚本读取100行文件。 lines[:]将包含100行。 同时,del lines[i]将继续删除项目。

最终,for循环将达到第100个元素。如果存在,即使只有一个del操作,del lines[99]也将失败并抛出IndexError。

因此,当删除时,行open('q0.txt', 'w').writelines(lines)将永远不会被执行。因此,文件继续保持不变。

这是我的理解。

答案 1 :(得分:1)

由于raw_input阻止了您的代码,您可能希望将该流程分成两个threads:您在代码中创建的main一个。由于线程以不可预测的顺序(有点)同时运行,因此您无法在中断到达主while循环的哪一行上完全控制 。线程是一个非常棘手的部分,它需要很多阅读,测试和检查事情发生的原因......

此外,由于您不介意消费您的线路,您可以执行所谓的破坏性读取操作:将文件内容加载到lines变量,并继续使用pop()获取最后一个,直到消耗掉线(或标志已激活)。检查pop()方法在列表中的作用。请注意,pop()始终返回列表的最后一个项。如果您希望按原始顺序打印商品,则必须使用之前shift列表中的reversedpop

import threading

interrupt=None

def flag_activator():
    global interrupt
    interrupt = raw_input("(!!) Type yes when you wanna stop\n\n")
    print "Oh gosh! The user input %s" % interrupt

th = threading.Thread(target=flag_activator)
th.start()


fr = open('q0.txt', 'r')
lines = fr.readlines()
fr.close()

while lines and interrupt != 'yes':
    print "I read this line: %s" % lines.pop()

if len(lines) > 0:
    print "Crap! There are still lines"
    fw = open('q0.txt', 'w')
    fw.writelines(lines)
    fw.close()

现在,在您在终端上输入yes之前,该代码将阻止您的终端。

PS:不要忘记关闭已打开的文件(如果您不想明确致电close(),请参阅with声明here和{{ 3}})

编辑(根据OP对我的误解的评论):

如果您想要的是确保文件在脚本突然停止时不会包含已经处理过的行,那么实现这一目标的效率低(但直截了当)就是:

  1. 打开文件进行读写(您每次操作都需要不同的文件描述符)
  2. 将所有文件的行加载到变量
  3. 处理第一行
  4. 从列表变量
  5. 中删除该行
  6. 将剩余列表写入文件
  7. 重复,直到不再加载
  8. 然而,所有这些文件的打开/关闭确实非常低效,但在这里:

    done = False
    while done == False:
        with open("q0.txt", 'r') as fr, open("q0.txt", 'w') as fw:
            lines = fr.readlines()
            if len(lines) > 0:
                print lines[0] # This would be your processing
                del lines[0]
                fw.writelines(lines)
            else:
                done = True