如何在Python中读取文件的每一行,并将每一行存储为列表中的元素?

我想逐行读取文件,并将每一行附加到列表的末尾。


当前回答

如果要包含以下内容:

with open(fname) as f:
    content = f.readlines()

如果不希望包含:

with open(fname) as f:
    content = f.read().splitlines()

其他回答

最简单的方法

一个简单的方法是:

将整个文件作为字符串读取逐行拆分字符串

在一行中,这将给出:

lines = open('C:/path/file.txt').read().splitlines()

然而,这是一种非常低效的方式,因为这将在内存中存储两个版本的内容(对于小文件来说可能不是大问题,但仍然如此)。[谢谢Mark Amery]。

有两种更简单的方法:

将文件用作迭代器

lines = list(open('C:/path/file.txt'))
# ... or if you want to have a list without EOL characters
lines = [l.rstrip() for l in open('C:/path/file.txt')]

如果您使用的是Python 3.4或更高版本,最好使用pathlib为文件创建一个路径,该路径可以用于程序中的其他操作:

from pathlib import Path
file_path = Path("C:/path/file.txt") 
lines = file_path.read_text().split_lines()
# ... or ... 
lines = [l.rstrip() for l in file_path.open()]

如果你面对一个非常大/巨大的文件,并且想读得更快(假设你在TopCoder或HackerBank编码竞赛中),你可以一次将相当大的行块读入内存缓冲区,而不只是在文件级别逐行迭代。

buffersize = 2**16
with open(path) as f:
    while True:
        lines_buffer = f.readlines(buffersize)
        if not lines_buffer:
            break
        for line in lines_buffer:
            process(line)

我喜欢使用以下内容。立即阅读台词。

contents = []
for line in open(filepath, 'r').readlines():
    contents.append(line.strip())

或者使用列表理解:

contents = [line.strip() for line in open(filepath, 'r').readlines()]

您可以按照建议简单地执行以下操作:

with open('/your/path/file') as f:
    my_lines = f.readlines()

请注意,这种方法有两个缺点:

1) 你把所有的行都存储在内存中。在一般情况下,这是一个非常糟糕的主意。文件可能非常大,内存可能会用完。即使它不大,也只是在浪费内存。

2) 这不允许在读取每行时对其进行处理。因此,如果在这之后处理行,则效率不高(需要两次而不是一次)。

对于一般情况,更好的方法如下:

with open('/your/path/file') as f:
    for line in f:
        process(line)

您可以任意定义流程函数。例如:

def process(line):
    if 'save the world' in line.lower():
         superman.save_the_world()

(超人类的实现留给您作为练习)。

这对于任何文件大小都很有效,您只需一次就可以完成文件。这就是一般解析器的工作原理。

下面是我用来简化文件I/O的Python(3)助手库类:

import os

# handle files using a callback method, prevents repetition
def _FileIO__file_handler(file_path, mode, callback = lambda f: None):
  f = open(file_path, mode)
  try:
    return callback(f)
  except Exception as e:
    raise IOError("Failed to %s file" % ["write to", "read from"][mode.lower() in "r rb r+".split(" ")])
  finally:
    f.close()


class FileIO:
  # return the contents of a file
  def read(file_path, mode = "r"):
    return __file_handler(file_path, mode, lambda rf: rf.read())

  # get the lines of a file
  def lines(file_path, mode = "r", filter_fn = lambda line: len(line) > 0):
    return [line for line in FileIO.read(file_path, mode).strip().split("\n") if filter_fn(line)]

  # create or update a file (NOTE: can also be used to replace a file's original content)
  def write(file_path, new_content, mode = "w"):
    return __file_handler(file_path, mode, lambda wf: wf.write(new_content))

  # delete a file (if it exists)
  def delete(file_path):
    return os.remove() if os.path.isfile(file_path) else None

然后使用FileIO.lines函数,如下所示:

file_ext_lines = FileIO.lines("./path/to/file.ext"):
for i, line in enumerate(file_ext_lines):
  print("Line {}: {}".format(i + 1, line))

请记住,mode(默认为“r”)和filter_fn(默认为检查空行)参数是可选的。

您甚至可以删除read、write和delete方法,只保留FileIO.line,甚至将其转换为一个单独的方法read_lines。