【问题标题】:Perform an operation during the last iteration of a for loop in python在python中for循环的最后一次迭代期间执行操作
【发布时间】:2012-07-16 15:52:14
【问题描述】:

我有一个循环解析文本文件的行:

for line in file:
    if line.startswith('TK'):
        for item in line.split():
            if item.startwith('ID='):
                *stuff*
            if last_iteration_of_loop
                *stuff*

我需要做一些作业,但直到第二个 for 循环的最后一次迭代才能完成。有没有办法检测到这一点,或者知道我是否在line.split() 的最后一项?请注意,第二个 for 循环中的 items 是字符串,它们的内容在运行时是未知的,所以我无法在最后寻找特定的字符串作为标志让我知道。

谢谢!

【问题讨论】:

    标签: python for-loop


    【解决方案1】:

    只参考for循环外的最后一行:

    for line in file:
        if line.startswith('TK'):
            item = None
            for item in line.split():
                if item.startwith('ID='):
                    # *stuff*
    
            if item is not None:
                # *stuff*
    

    item 变量在 for 循环之外仍然可用:

    >>> for i in range(5):
    ...     print i
    ... 
    0
    1
    2
    3
    4
    >>>  print 'last:', i
    last: 4
    

    请注意,如果您的文件为空(循环中没有迭代)item 将不会被设置;这就是为什么我们在循环之前设置item = None 并在之后测试if item is not None

    如果您必须有 与您的测试匹配的最后一项,请将其存储在新变量中:

    for line in file:
        if line.startswith('TK'):
            lastitem = None
            for item in line.split():
                if item.startwith('ID='):
                    lastitem = item
                    # *stuff*
    
            if lastitem is not None:
                 # *stuff*
    

    第二个选项的演示:

    >>> lasti = None
    >>> for i in range(5):
    ...     if i % 2 == 0:
    ...         lasti = i
    ...
    >>> lasti
    4
    

    【讨论】:

    • elsefor 循环是完全没有意义的循环中没有 break 语句。
    • 通常情况下,我会同意这种方法(同意@SvenMarnach)。但是,如果 OP 在打印出来之前必须对 4 做一些事情怎么办?这在这个结构中效果不佳
    • 我认为它没有记录任何内容。即使是惯用的 for/else 也让人们感到困惑,但这确实令人困惑。
    • 啊,是的,我忘记了 break 跳过任何 else 子句...因此必须倾向于同意您最初的评论。
    • @Martijn Pieters:这样更好。
    【解决方案2】:

    试试这个:

    for line in file:
        if line.startswith('TK'):
            items = line.split()
            num_loops = len(items)
            for i in range len(items):
                item = items[i]
                if item.startwith('ID='):
                    *stuff*
                if i==num_loops-1: # if last_iteration_of_loop
                    *stuff*
    

    希望有帮助

    【讨论】:

      【解决方案3】:

      不知道为什么你不能只在最终循环之外修改,但你可以利用它——它适用于任何迭代器,而不仅仅是那些已知长度的迭代器......

      未经广泛测试,可能效率不高

      from itertools import tee, izip_longest, count
      
      def something(iterable):
          sentinel = object()
          next_count = count(1)
      
          iterable = iter(iterable)
          try:
              first = next(iterable)
          except StopIteration:
              yield sentinel, 'E', 0 # empty
      
          yield first, 'F', next(next_count) # first
      
          fst, snd = tee(iterable)
          next(snd)
          for one, two in izip_longest(fst, snd, fillvalue=sentinel):
              yield one, 'L' if two is sentinel else 'B', next(next_count) # 'L' = last, 'B' = body
      

      【讨论】:

        猜你喜欢
        • 2011-07-11
        • 1970-01-01
        • 1970-01-01
        • 2020-10-01
        • 2013-05-17
        • 2016-05-10
        • 2016-08-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多