python - 使用 Python 从文本文件中删除一行

标签 python file-io

我有一个文件,其中每一行都以数字开头。用户可以通过键入用户想要删除的行号来删除行。

我遇到的问题是设置打开它的模式。当我使用a+时,原来的内容还在。但是,附加到文件末尾的是我想要保留的行。另一方面,当我使用 w+ 时,整个文件都被删除了。我确信有比使用 w+ 模式打开它,删除所有内容,然后重新打开它并附加行更好的方法。

 def DeleteToDo(self):
    print "Which Item Do You Want To Delete?"
    DeleteItem = raw_input(">") #select a line number to delete
    print "Are You Sure You Want To Delete Number" + DeleteItem + "(y/n)"
    VerifyDelete = str.lower(raw_input(">"))
    if VerifyDelete == "y":
        FILE = open(ToDo.filename,"a+") #open the file (tried w+ as well, entire file is deleted)
        FileLines = FILE.readlines() #read and display the lines
        for line in FileLines:
            FILE.truncate()
            if line[0:1] != DeleteItem: #if the number (first character) of the current line doesn't equal the number to be deleted, re-write that line
                FILE.write(line)
    else:
        print "Nothing Deleted"

这是典型文件的样子

1. info here
2. more stuff here
3. even more stuff here

最佳答案

当您打开一个文件进行写入时,您会破坏该文件(删除其当前内容并开始一个新文件)。您可以通过阅读有关 open() 命令的文档来了解这一点。

当您打开一个文件进行追加时,您不会破坏该文件。但是你怎么能只删除一行呢?文件是存储在存储设备上的字节序列;您无法删除一行并让所有其他行自动“滑下”到存储设备上的新位置。

(如果您的数据存储在数据库中,您实际上可以从数据库中删除一个“行”;但文件不是数据库。)

因此,解决此问题的传统方法是:从原始文件中读取,然后将其复制到新的输出文件中。在复制时,您可以执行任何所需的编辑;例如,您可以简单地通过不复制一行来删除该行;或者您可以通过在新文件中写入来插入一行。

然后,一旦您成功写入新文件并成功关闭它,如果没有错误,您继续将新文件重命名回与旧文件相同的名称(这会破坏旧文件)。

在 Python 中,你的代码应该是这样的:

import os

# "num_to_delete" was specified by the user earlier.

# I'm assuming that the number to delete is set off from
# the rest of the line with a space.

s_to_delete = str(num_to_delete) + ' '
def want_input_line(line):
    return not line.startswith(s_to_delete)

in_fname = "original_input_filename.txt"
out_fname = "temporary_filename.txt"

with open(in_fname) as in_f, open(out_fname, "w") as out_f:
    for line in in_f:
        if want_input_line(line):
            out_f.write(line)

os.rename(out_fname, in_fname)

请注意,如果您碰巧有一个名为 temporary_filename.txt 的文件,它将被此代码破坏。我们真的不关心文件名是什么,我们可以使用 tempfile 模块让 Python 为我们创建一些唯一的文件名。

任何最新版本的 Python 都允许您在单个 with 语句中使用多个语句,但如果您碰巧使用 Python 2.6 或其他版本,您可以嵌套两个 with获得相同效果的语句:

with open(in_fname) as in_f:
    with open(out_fname, "w") as out_f:
        for line in in_f:
            ... # do the rest of the code

另外,请注意我没有使用.readlines() 方法来获取输入行,因为.readlines() 读取将文件的全部内容一次全部存入内存,如果文件非常大,这将很慢甚至可能无法工作。您可以使用从 open() 返回的“文件对象”简单地编写一个 for 循环;这将一次给你一行,你的程序甚至可以处理非常大的文件。

编辑:请注意,我的回答是假设您只想执行一个编辑步骤。正如@jdi 在对另一个答案的评论中指出的那样,如果您想允许用户可以删除多行或插入行或其他任何内容的“交互式”编辑,那么最简单的方法实际上是使用将所有行读入内存.readlines(),在结果列表中插入/删除/更新/任何内容,然后在编辑完成后仅将列表写入文件一次。

关于python - 使用 Python 从文本文件中删除一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11249966/

相关文章:

ios - 使用 DocumentPicker 选择多个文件 - iOS

Java-输出不打印

c - 为什么那个功能不起作用?

Python IMAP 搜索,搜索结果耗尽所有内存

python - OpenCV + Python + GigE 视觉相机

python - 将行和列插入 numpy 数组

python - 每次打开/关闭文件与保持打开直到过程完成更好吗?

Java文件输入编译后不起作用

python - 从 Azure 凭据检索 ID/电子邮件

python - 使用 Pandas 根据之前所有对信息构建新列