【问题标题】:How to advance a for loop by 2 iterations?如何将 for 循环推进 2 次迭代?
【发布时间】:2016-11-22 16:51:46
【问题描述】:

我正在读取一个大文本文件,我需要从特定行读取一个数字。该文件如下所示:

....
unknown number of lines
....
ABCD
some random stuff
a number I want to read
....
....

我想从 ABCD 的“签名”行之后的 2 行中读取数字,这是唯一的。现在我正在做的是:

with open(filename,'r') as f:
  for line in f:
    if line.rstrip('\n') == 'ABCD':
      continue

continue 仅将 for 循环推进 1 次迭代。那么,我怎样才能让它再推进一次迭代以获得我真正需要的线呢?

【问题讨论】:

  • 显而易见的选择是使用re 进行正则表达式。尝试使用re.match(r'\d*', your_text) 或类似的方式提取此号码。

标签: python python-3.x for-loop file-io


【解决方案1】:

您可以在 f* 上显式调用 next(for 循环通常为您执行此操作)并推进迭代器,然后调用 continue

for line in f:
    if line.rstrip('\n') == 'ABCD':
        next(f)
        continue
    print(line)

现在将打印:

....

unknown number of lines

....

a number I want to read

....

....

从而跳过'ABCD''some random stuff'

在您确定ABCD 不是最终元素的一般情况下,这不会引起问题。但是,如果您想安全起见,可以将其包装在 try - except 中以捕获 StopIteration 异常。


* 在这种情况下,这是可行的,因为f 是它自己的iterator,即iter(f) is f。一般来说,情况并非如此,对于列表,迭代器是它自己的不同对象list_iterator,所以像这样推进它是行不通的。

【讨论】:

  • 请注意,这仅在 f 是迭代器时才有效。文件可能就是这种情况,但如果flist,那么执行此操作会出错。 (您当然可以通过创建和迭代器并将其分配给循环之前的变量然后将其用作循环的对象来解决此问题。)
  • @jpmc26 确实如此;我会补充一下,因为其他人碰到这个可能会感到困惑。
【解决方案2】:

如果您想坚持使用这种方法,请执行以下操作:

f = open(filename,'r'):
while f.readline().rstrip('\n') != 'ABCD': # this will advanced the pointer to the ABCD line
    continue
f.next() # to skip over the unnecessary stuff
desiredNumber = f.readline()  # desired line

我认为正则表达式看起来会好很多,但如果你想要完成工作,这里就是。

【讨论】:

    【解决方案3】:

    如果您根本不需要跳过的行中的任何信息,您可以在continueing 之前手动将文件前进一行:

    with open(filename,'r') as f:
        for line in f:
            if line.rstrip('\n') == 'ABCD':
                next(f)     # The next iteration of the for loop will skip a line
                continue
    

    如果您需要从这个文件中唯一的东西是那一行,那么根本不需要continue。只需跳过一行,抓住下一行,做任何你需要做的事情,然后break 退出for 循环,所有这些都来自if 块。

    【讨论】:

    • 通常最好使用next 而不是readline。我不知道 Python 3 做出了什么承诺,但在 Python 2 上,混合文件迭代和 readline 明确不起作用。
    【解决方案4】:

    我更喜欢@Jim 使用next(),但另一种选择是只使用一个标志:

    with open(filename,'r') as f:
      skip_line = False
      for line in f:
        if line.rstrip('\n') == 'ABCD':
          skip_line = True
          continue
      if skip_line == True:
        skip_line = False
      else:
        print(line)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-14
      相关资源
      最近更新 更多