我想逐行读取python中的文件,但在某些情况下(基于if条件)我还想读取文件中的下一行,然后继续以相同的方式读取它
示例:
file_handler = open(fname, 'r')
for line in file_handler:
if line[0] == '#':
print line
else:
line2 = file_handler.readline()
print line2
基本上在这个例子中我试图逐行读取它,但是当行不以#
开头时我想读下一行,打印它,然后继续阅读该行2号线。这只是一个例子,我在代码中遇到类似的错误,但我的目标是标题中所述。
但我会收到类似ValueError: Mixing iteration and read methods would lose data
的错误。
是否有可能以更聪明的方式做我想做的事情?
答案 0 :(得分:6)
如果您只想跳过不以#
开头的行,可以采用更简单的方法:
file_handler = open(fname, 'r')
for line in file_handler:
if line[0] != '#':
continue
# now do the regular logic
print line
显然,这种简单的逻辑在所有可能的情况下都不起作用。如果没有,则必须完全按照错误的含义执行:一致地使用迭代,或者一致地使用读取方法。这将更加繁琐且容易出错,但 不好。
例如,使用readline
:
while True:
line = file_handler.readline()
if not line:
break
if line[0] == '#':
print line
else:
line2 = file_handler.readline()
print line2
或者,迭代:
lines = file_handler
for line in file_handler:
if line[0] == '#':
print line
else:
print line
print next(file_handler)
但是,最后一个版本有点像“作弊”。您依赖于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,)
答案 1 :(得分:1)
file_handler = open(fname, 'r')
for line in file_handler:
if line.startswith('#'): # <<< comment 1
print line
else:
line2 = next(file_handler) # <<< comment 2
print line2
您的代码使用了一个等号,这是不正确的。它应该是双等号用于比较。我建议使用.startswith()函数来增强代码清晰度。
使用next()
函数前进到下一行,因为您使用file_handler
作为迭代器。
答案 2 :(得分:0)
添加标志值:
if flag is True:
print line #or whatever
flag = False
if line[0] == '#':
flag = True
这是多功能版本: - )
答案 3 :(得分:0)
您可以保存一些状态信息,告诉您如何处理下一行:
want_next = False
for line in open(fname):
if want_next:
print line
want_next = False
elif line[0] == '#':
print line
want_next = True
答案 4 :(得分:0)
我认为你要找的是next
而不是readline
。
一些东西。在您的代码中,您使用=而不是==。我将使用startswith代替。如果在迭代器上调用next,它将返回下一个项目或抛出StopIteration异常。
文件
ewolf@~ $cat foo.txt
# zork zap
# woo hoo
here is
some line
# a line
with no haiku
该计划
file_handler = open( 'foo.txt', 'r' )
for line in file_handler:
line = line.strip()
if line.startswith( '#' ):
print "Not Skipped : " + line
elif line is not None:
try:
l2 = file_handler.next()
l2 = l2.strip()
print "Skipping. Next line is : " + l2
except StopIteration:
# End of File
pass
输出
Not Skipped : # zork zap
Not Skipped : # woo hoo
Skipping. Next line is : some line
Not Skipped : # a line
Skipping. Next line is :
答案 5 :(得分:-2)
尝试if line[0] == "#"
而不是行[0] =“#”