Python3中是否有内置的"take(iterable,n)"函数



我只是在一些嵌套生成器中滥用StopIteration(使用CPython 3.6.9(,没有启用PEP 479(from __future__ import generator_stop(,并且有一些使用next(iter(iterable))的错误代码过早地发出了停止信号。

虽然PEP479会从生成器中捕获StopIteration,但我想我仍然会在嵌套的for循环中遇到这种情况。

现在,我将用以下内容替换next(iter(...))的任何用法:

def take(iterable, *, n):
"""
Robustly gets the first n items from an iterable and returns them as a
list.
You should always use this function in lieu of `next(iter(...))`! e.g.
instead of:
my_first = next(iter(container))
you should instead do:
my_first, = take(container, n=1)
Throws RuntimeError if the iterable cannot yield n items.
"""
iterator = iter(iterable)
out = []
for _ in range(n):
try:
out.append(next(iterator))
except StopIteration:
raise RuntimeError("Premature StopIteration encountered!")
return out

我的问题是:Python的stdlib中已经有这样的函数了吗?

我查看了itertoolsbuiltinspython.org的最新文档(3.9(,我能看到的最接近的是takewhile,但我对此很感兴趣。我也可以转换为list或任何其他可索引容器,但我希望避免只为了访问第一件事而迭代所有内容。

itertools.islice可以做到这一点(以及更多(,而无需转换为列表,也无需在生成的元素不足时出错。

你可以用这个干净的方式来写你的函数:

def take(iterable, *, n):
li = list(itertools.islice(iterable, n))
if len(li) != n:
raise RuntimeError("too short iterable for take")
return li

相关内容

  • 没有找到相关文章

最新更新