如何解决Python3中是否有内置的`takeiterable,n`函数?
我只是在一些嵌套生成器中滥用StopIteration
(使用CPython 3.6.9),没有启用PEP 479(from __future__ import generator_stop
),并且有一些糟糕的hacky代码,使用next(iter(iterable))
表示过早停车。
尽管PEP 479会阻止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中已经有这样的函数吗?
我在python.org
和itertools
中查看了builtins
的最新文档(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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。