Python中查找可迭代元素是否最后一个的标准方法



如果我在Python的迭代器中循环,我如何找出现在是否是最后一个元素?我正在寻找一些标准的库方法来实现这一点,也许是itertools中的一些函数,有这样的吗?或者其他一些短小精悍的方式。

当然,我可以实现我自己的助手生成器来完成这项任务:

在线试用!

def is_last(it):
first = True
for e in it:
if not first:
yield False, prev
else:
first = False
prev = e
if not first:
yield True, prev
for last, e in is_last(range(4)):
print(last, e)

哪个输出:

False 0
False 1
False 2
True 3

此外,如果我在简单范围内循环,我总是可以与上限进行比较(下面是正step的解决方案(:

在线试用!

start, stop, step = 10, 21, 3
for i in range(start, stop, step):
last = i + step >= stop
print(last, i)

哪个输出:

False 10
False 13
False 16
True 19

对于简单范围的情况,上述内容也是显而易见的,可能也是最简单的解决方案,不幸的是,它需要在单独的变量中保持stop/step。但无论如何,范围的情况并不是很有趣。对于任意迭代器的情况,有没有Python方法可以解决这种情况?

我以前用过这样的东西。这不是一个好的解决方案,因为它很容易被滥用,但它可以工作。

def peek(itr: Iterator[T]) -> Tuple[Optional[T], Optional[Iterator[T]]]:
"""
Return a pair of (first element of iterator, new iterator).  If iterator is exhausted, return (None, None).
https://stackoverflow.com/a/664239/3282436
NOTE: Because checking for values consumes part of the supplied iterator, that iterator is invalidated.  To continue
iterating, you *must* use the iterator returned from peek.
>>> itr = iter(range(3))
>>> if recipes.peek(itr)[0] == 0:  # WRONG, itr will be missing first element
>>>     # ...
>>> itr = iter(range(3))
>>> first, itr = recipes.peek(itr)  # Correct
>>> if first == 0:
>>>     # ...
"""
try:
first = next(itr)
except StopIteration:
return None, None
return first, itertools.chain([first], itr)

相关内容

最新更新