在Python中读取文件时忽略空行的最简单方法
我有一些代码,它可以读取一个名字的文件,并创建一个名字列表:
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
就可以了。