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

Dna*_*iel 2 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
Run Code Online (Sandbox Code Playgroud)

基本上在这个例子中我试图逐行读取它,但是当行没有开始时#我想读下一行,打印它,然后继续读取line2之后的行.这只是一个例子,我在代码中遇到类似的错误,但我的目标是标题中所述.

但是我会得到一个错误ValueError: Mixing iteration and read methods would lose data.

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

aba*_*ert 6

如果你只是想跳过没有开头的行#,那么有一个更简单的方法:

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)