在命名文件中读取最pythonic的方法是什么,剥离为空的行,仅包含空格,或者将#作为第一个字符,然后处理剩余的行?假设它很容易适合记忆。
注意:这样做并不困难 - 我要求的是最狡猾的方式。我一直在写很多Ruby和Java,但我已经失去了感觉。
这是一个稻草人:
file_lines = [line.strip() for line in open(config_file, 'r').readlines() if len(line.strip()) > 0]
for line in file_lines:
if line[0] == '#':
continue
# Do whatever with line here.
我对简洁感兴趣,但不是以难以阅读为代价。
答案 0 :(得分:5)
发电机非常适合这样的任务。它们是可读的,保持完美的关注点分离,并有效地记忆使用和时间。
def RemoveComments(lines):
for line in lines:
if not line.strip().startswith('#'):
yield line
def RemoveBlankLines(lines):
for line in lines:
if line.strip():
yield line
现在将这些应用到您的文件中:
filehandle = open('myfile', 'r')
for line in RemoveComments(RemoveBlankLines(filehandle)):
Process(line)
在这种情况下,很明显两个生成器可以合并为一个,但我将它们分开来展示它们的可组合性。
答案 1 :(得分:3)
lines = [r for r in open(thefile) if not r.isspace() and r[0] != '#']
字符串的.isspace()
方法是测试字符串是否完全是空格的最佳方法 - 不需要像len(r.strip()) == 0
(ech; - )那样的扭曲。
答案 2 :(得分:2)
for line in open("file"):
sline=line.strip()
if sline and not sline[0]=="#" :
print line.strip()
输出
$ cat file
one
#
#
two
three
$ ./python.py
one
two
three
答案 3 :(得分:1)
我会用这个:
processed = [process(line.strip())
for line in open(config_file, 'r')
if line.strip() and not line.strip().startswith('#')]
我在这里看到的唯一的丑陋是所有重复的剥离。摆脱它使功能变得复杂:
processed = [process(line)
for line in (line.strip() for line in open(config_file, 'r'))
if line and not line.startswith('#')]
答案 4 :(得分:1)
这符合描述,即
剥去空行, 只包含空格,或者#为a 第一个字符,然后处理 剩下的行
因此,在空格中开始或结束的行将不受约束地传递。
with open("config_file","r") as fp:
data = (line for line in fp if line.strip() and not line.startswith("#"))
for item in data:
print repr(item)
答案 5 :(得分:1)
我喜欢Paul Hankin的想法,但我会采用不同的方式:
from itertools import ifilter, ifilterfalse, imap
with open(r'c:\temp\testfile.txt', 'rb') as f:
s1 = ifilterfalse(str.isspace, f)
s2 = ifilter(lambda x: not x.startswith('#'), s1)
s3 = imap(str.rstrip, s2)
print "\n".join(s3)
如果我担心内存使用情况,我可能只会这样做,而不是使用这里建议的一些更明显的方法。我可以定义一个iscomment
函数来消除lambda。
答案 6 :(得分:0)
文件很小,因此性能不是问题。我会说清楚而不是简洁:
fp = open('file.txt')
for line in fp:
line = line.strip()
if line and not line.startswith('#'):
# process
fp.close()
如果需要,可以将其包装在一个函数中。
答案 7 :(得分:0)
使用稍微更新的习语(或使用Python 2.5 from __future__ import with
)你可以做到这一点,它具有安全清理的优点,但非常简洁。
with file('file.txt') as fp:
for line in fp:
line = line.strip()
if not line or line[0] == '#':
continue
# rest of processing here
请注意,首先删除该行意味着检查“#”实际上会拒绝具有第一个非空白的行,而不仅仅是“作为第一个字符”。如果您对此严格要求,则很容易修改。