在Python中读取文件时忽略空行的最简单方法

67 投票
10 回答
182850 浏览
提问于 2025-04-16 10:53

我有一些代码,它可以读取一个名字的文件,并创建一个名字列表:

names_list = open("names", "r").read().splitlines()

每个名字之间用换行符分隔,像这样:

Allman
Atkinson

Behlendorf 

我想忽略那些只包含空格的行。我知道可以通过创建一个循环,检查我读取的每一行,如果不是空的就把它加到列表里。

我只是想知道有没有更符合Python风格的方法来做到这一点?

10 个回答

13

如果你想的话,可以把你之前的代码放在一个列表推导式里:

names_list = [line for line in open("names.txt", "r").read().splitlines() if line]

或者

all_lines = open("names.txt", "r").read().splitlines()
names_list = [name for name in all_lines if name]

这里的splitlines()已经把每行的结尾符号去掉了。

不过我觉得这样写不如直接用循环来得清晰:

names_list = []
with open('names.txt', 'r') as _:
    for line in _:
        line = line.strip()
        if line:
            names_list.append(line)

补充:

不过,使用filter函数看起来也很简洁易读:

names_list = filter(None, open("names.txt", "r").read().splitlines())

28

你可以使用列表推导式:

with open("names", "r") as f:
    names_list = [line.strip() for line in f if line.strip()]

更新:去掉了不必要的 readlines()

为了避免调用 line.strip() 两次,你可以使用生成器:

names_list = [l for l in (line.strip() for line in f) if l]
93

我会把生成器表达式叠加起来:

with open(filename) as f_in:
    lines = (line.rstrip() for line in f_in) # All lines including the blank ones
    lines = (line for line in lines if line) # Non-blank lines

现在,lines 就是所有非空的行。这可以让你避免对同一行调用两次去掉空格的操作。如果你想要一份行的列表,你可以直接这样做:

with open(filename) as f_in:
    lines = (line.rstrip() for line in f_in) 
    lines = list(line for line in lines if line) # Non-blank lines in a list

你也可以把它写成一行(不算with语句),但这样并不会更高效,而且更难读:

with open(filename) as f_in:
    lines = list(line for line in (l.strip() for l in f_in) if line)

更新:

我同意这样写很丑,因为有重复的部分。如果你更喜欢的话,可以直接写一个生成器:

def nonblank_lines(f):
    for l in f:
        line = l.rstrip()
        if line:
            yield line

然后像这样调用它:

with open(filename) as f_in:
    for line in nonblank_lines(f_in):
        # Stuff

更新 2:

with open(filename) as f_in:
    lines = filter(None, (line.rstrip() for line in f_in))

在 CPython(使用确定性的引用计数)中:

lines = filter(None, (line.rstrip() for line in open(filename)))

在 Python 2 中,如果你想要一个生成器,可以使用 itertools.ifilter,而在 Python 3 中,如果你想要一个列表,只需把整个内容传给 list 就可以了。

撰写回答