我想逐行读取python中的文件,但在某些情况下(基于if条件)我还想读取文件中的下一行,然后继续以相同的方式读取它.
例:
file_handler = open(fname, 'r')
for line in file_handler:
if line[0] == '#':
print line
else:
line2 = file_handler.readline()
print line2
Run Code Online (Sandbox Code Playgroud)
基本上在这个例子中我试图逐行读取它,但是当行没有开始时#我想读下一行,打印它,然后继续读取line2之后的行.这只是一个例子,我在代码中遇到类似的错误,但我的目标是标题中所述.
但是我会得到一个错误ValueError: Mixing iteration and read methods would lose data.
是否有可能以更聪明的方式做我想做的事情?
如果你只是想跳过没有开头的行#,那么有一个更简单的方法:
file_handler = open(fname, 'r')
for line in file_handler:
if line[0] != '#':
continue
# now do the regular logic
print line
Run Code Online (Sandbox Code Playgroud)
显然,这种简单的逻辑在所有可能的情况下都不起作用.如果没有,则必须完全按照错误的含义进行操作:一致地使用迭代,或者一致地使用读取方法.这将更加繁琐且容易出错,但并不是那么糟糕.
例如,用readline:
while True:
line = file_handler.readline()
if not line:
break
if line[0] == '#':
print line
else:
line2 = file_handler.readline()
print line2
Run Code Online (Sandbox Code Playgroud)
或者,迭代:
lines = file_handler
for line in file_handler:
if line[0] == '#':
print line
else:
print line
print next(file_handler)
Run Code Online (Sandbox Code Playgroud)
但是,最后一个版本有点像"作弊".您依赖于for循环中的迭代器与创建它的迭代相同的事实.这恰好适用于文件,但不适用于列表.所以,你应该在while True这里做同样的循环,除非你想要添加一个显式iter调用(或者至少是一个解释为什么你不需要它的注释).
更好的解决方案可能是编写一个生成器函数,根据您的规则将一个迭代器转换为另一个迭代器,然后打印出该生成器迭代的每个值:
def doublifier(iterable):
it = iter(iterable)
while True:
line = next(it)
if line.startswith('#'):
yield line, next(it)
else:
yield (line,)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1453 次 |
| 最近记录: |