python - Python中查找可迭代元素是否是最后一个的标准方法?
问题描述
如果我正在循环遍历 Python 的迭代器,我如何确定 now 是否是最后一个元素?我正在寻找一些标准库的方法,也许是一些函数itertools
,有这样的吗?或者其他一些非常简短和 Pythonic 的方式来做到这一点。
当然,我可以实现自己的辅助生成器来完成此任务:
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
对于简单范围的情况,上述这也是显而易见的并且可能是最简单的解决方案,不幸的是它需要将停止/步进保持在单独的变量中。但无论如何,范围案例并不是很有趣。任何任意迭代器的情况如何,是否有 Pythonic 的方法来解决这种情况?
解决方案
我以前用过这样的东西。这不是一个很好的解决方案,因为它很容易被滥用,但它可以工作。
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)
推荐阅读
- javascript - 防止功能组件使用默认值覆盖数据
- nginx - Nginx:缓存 Brotli 压缩代理上游响应
- r - 使用特定过滤器进行汇总
- powershell - 如何将参数列表中的类对象传递给另一台计算机并在其上调用函数?
- ios - 如何修复 Xcode 中的“固定宽度约束可能导致剪辑”警告?
- hive - HIVE 中的空桶
- c# - 如何将标签页的上下文绑定到 Xamarin 的 CS 代码中的其他页面?
- r - R:在 plm 中过滤数据
- flutter - 如何将图像处理路由转换添加到 Flutter
- paypal - 捕获订阅智能按钮与 SDK 集成的错误 - Sandbox 和 Live