如何使用 python 中的文件处理在文本文件中写入特定部分?

问题描述 投票:0回答:5

我在一个项目中工作,想在一个文本文件中打印多行。 这是我为此目的使用的方法。

def story_part(file_path,initial_index,final_index):
    line_number = list(range((initial_index -1) ,final_index ))
    mylines = []

    with open(file_path) as f:
        for i , line in enumerate(f):
            if i in line_number:

                mylines.append(line.rstrip())
            elif i > final_index:
                break
    for content in mylines:
        print(content)

你能输入更高效的代码吗?

我试图打印文本文件中的指定部分。 我搜索了几个网站,但没有找到帮助。

在摸索了一段时间后,我有了这个功能。 这是正确的方法吗,或者你可以帮助它改进。

python python-3.x function file-handling with-statement
5个回答
1
投票

我建议看看

.readlines
方法和切片,这可以让你输出更简洁的行范围,比如说如果我需要
file.txt
的第5,6,7,8,9,10行我可以按照以下方式进行方式

with open("file.txt") as f:
    lines = f.readlines()[4:10]
    print(''.join(lines), end='')

.readlines()
返回包含尾随换行符的行列表,
[4:10]
就是所谓的 slicing,它允许您获取列表的切片。然后我们使用空字符串连接行(因为它们已经有了换行符)并将结束设置为空字符串(同样,由于换行符已经存在)。


1
投票

您可以在代码中进行的一项优化(无需更改太多)是使您的

line_number
成为
set
以便索引查找变得恒定。

i in [1 2 3] # O(n) 
i in {1 2 3} # O(1)

目前的答案完全没问题。但是,

read()
,
readlines()
,
splitlines()
将整个数据加载到内存中。当文件大时,这可能不是很可扩展。

您可能会使用

itertools
作为迭代器读取文件。

from itertools import islice
def story_part(file_path,initial_index,final_index):

    with open(file_path, "r") as f:
        # islice the file iterator from start index to end index. (You can also pass a step to islice)
        # map your rstrip to each line that is read.
        # list call is not necessary here if you are looping over the data later on.
        mylines = list(map(str.rstrip, islice(f, initial_index-1, final_index)))
    for content in mylines:
        print(content)

这种方式文件只读到

final_index
,并且只有所需的行才会加载到内存中。 (请注意,
initial_index
之前的所有文件行都将被读取,但会被忽略。)


0
投票

你不需要 for 循环。您只能通过 python 列表的切片功能来完成这项工作。

def story_part(file_path, initial_index, final_index):
    with open(file_path) as f:
        file_data = f.read().splitlines()

    mylines = file_data[initial_index-1:final_index]

    for content in mylines:
        print(content)

在上面的函数中,首先我读取数据并将其保存在一个名为

file_data
的变量中,该变量是文件中所有行的列表。请注意,使用
.read().splitlines()
.readlines()
更好,因为它省略了每行的
\n
字符。然后
file_data[initial_index-1:final_index]
代码只选择你想要的索引。之后,for 循环打印数据(包括这一行只是因为你的代码中有它。没有必要。)

此代码没有您使用的额外 for 循环和 if 语句。

你也可以像这样在更小的情况下编写上面建议的代码:

def story_part(file_path, initial_index, final_index):
    with open(file_path) as f:
        for content in f.read().splitlines()[initial_index-1:final_index]:
            print(content)

这是完全相同的代码,但没有额外的变量和代码分离。


0
投票

在可读性方面可以稍微提高一点,但您仍然必须浏览整个文件:

def story_part(file_path, initial_index, final_index):
    mylines = []

    with open(file_path) as f:
        for i, line in enumerate(f, start=1):
            if initial_index <= i <= final_index:
                mylines.append(line.rstrip())
            elif i > final_index:
                break

    for content in mylines:
        print(content)

注意避免在读取大文件时使用

f.readlines()
,因为它会将整个文件存储在内存中。


0
投票
def print_lines_file(file_path: str,initial_index: int = 0,final_index:int = 1):
    with open(file_path) as f:
        for i in f.readlines()[initial_index:final_index]:
            print(i)
© www.soinside.com 2019 - 2024. All rights reserved.