在Python的for循环的最后一次迭代期间执行一个操作。

3
我有一个循环正在解析文本文件的行:
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是字符串,并且它们的内容在运行时是未知的,因此我无法查找特定的字符串作为标志来让我知道我已经到达列表的末尾。

3个回答

9
只需参考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*
< p>for循环之外仍然可以使用item变量:

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

4
在循环中使用 else 而不带有 break 语句是完全没有意义的。 - Sven Marnach
1
通常情况下,我会同意这种方法(赞同@SvenMarnach的观点)。但是如果OP在打印之前必须对4进行某些操作呢?在这种结构中,这样做将不起作用。 - inspectorG4dget
啊,是的,我忘记了break会跳过任何else子句...所以我倾向于同意你最初的评论。 - martineau
@Martijn Pieters:这样更好。 - martineau
@ZakParks:使用我给你的第二个选项;如果有匹配行,lastline就是最后一行。 - Martijn Pieters
显示剩余6条评论

1

试试这个:

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*

希望这有所帮助。

0

不确定为什么您不能在最终循环之外进行修改,但您可能可以利用这个 - 它适用于任何迭代器,而不仅仅是已知长度的迭代器...

没有经过广泛测试,可能不太高效

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接