确定生成器中当前元素是否为第一个或最后一个元素的Pythonic方法?

4 投票
7 回答
1219 浏览
提问于 2025-04-16 17:31

我正在使用生成器,想知道在Python中,怎样才能判断当前元素是生成器中的第一个还是最后一个元素,因为这两个元素需要特别处理。

谢谢!

基本上我是在生成标签,所以我有一些像这样的项目:

<div class="first">1</div>
<div>...</div>
<div class="last">n</div>

所以我想在循环中保留最后一个项目?

7 个回答

2

首先,使用一个标记来表示你是否已经处理过任何数据。对于最后一个数据,可以把下一个值存放在一个变量里,如果没有更多的数据了,那就是最后一个数据。

3

我做这件事的方法和这里其他一些回答类似,不过这是我个人的偏好。也许你会觉得这种方式也适合你。

通过我下面的这个函数,我可以写出这样的代码:

values = [10, 11, 12, 13]
for i, val, isfirst, islast in enumerate2(values):
  if isfirst:
    print 'BEGIN...', val
  elif islast:
    print val, '... END'
  else:
    print val

下面是这个函数的定义:

def enumerate2(iterable_):
  it = iter(iterable_)
  try:
    e = it.next()
    isfirst = True
    i = 0
    try:
      while True:
        next_e = it.next()
        yield (i, e, isfirst, False)
        i += 1
        isfirst = False
        e = next_e
    except StopIteration:
      yield (i, e, isfirst, True)
  except StopIteration:
    pass
5

这是一个类似于枚举的生成器,它会跳过一个元素;对于最后一个元素,它会返回-1。

>>> def annotate(gen):
...     prev_i, prev_val = 0, gen.next()
...     for i, val in enumerate(gen, start=1):
...         yield prev_i, prev_val
...         prev_i, prev_val = i, val
...     yield '-1', prev_val
>>> for i, val in annotate(iter(range(4))):
...     print i, val
... 
0 0
1 1
2 2
-1 3

这个生成器无法判断传入的生成器是否是“新的”,但它仍然能告诉你什么时候快要结束了:

>>> used_iter = iter(range(5))
>>> used_iter.next()
0
>>> for i, val in annotate(used_iter):
...     print i, val
... 
0 1
1 2
2 3
-1 4

一旦迭代器用完了,它会像往常一样抛出一个 StopIteration 的错误。

>>> annotate(used_iter).next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in annotate
StopIteration

撰写回答