逐行读取文件,有时读取同一循环中的下一行

时间:2013-04-29 22:14:54

标签: python

我想逐行读取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的错误。

是否有可能以更聪明的方式做我想做的事情?

6 个答案:

答案 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

讨论

  1. 您的代码使用了一个等号,这是不正确的。它应该是双等号用于比较。我建议使用.startswith()函数来增强代码清晰度。

  2. 使用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] =“#”