如何从生成器中仅选取一项?
我有一个如下所示的生成器函数:
def myfunct():
...
yield result
调用该函数的通常方法是:
for r in myfunct():
dostuff(r)
我的问题是,有没有一种方法可以随时从生成器中获取一个元素? 例如,我想做类似的事情:
while True:
...
if something:
my_element = pick_just_one_element(myfunct())
dostuff(my_element)
...
I have a generator function like the following:
def myfunct():
...
yield result
The usual way to call this function would be:
for r in myfunct():
dostuff(r)
My question, is there a way to get just one element from the generator whenever I like?
For example, I'd like to do something like:
while True:
...
if something:
my_element = pick_just_one_element(myfunct())
dostuff(my_element)
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
(或在 Python 2.5 或更低版本中使用
g.next()
)创建生成器使用每次您想要一个项目时,使用
。
如果生成器退出,它将引发
StopIteration
。如果需要,您可以捕获此异常,或者使用next()
的default
参数:Create a generator using
Everytime you would like an item, use
(or
g.next()
in Python 2.5 or below).If the generator exits, it will raise
StopIteration
. You can either catch this exception if necessary, or use thedefault
argument tonext()
:要仅选取生成器的一个元素,请在
for
语句中使用break
或list(itertools.islice(gen, 1))
根据你的例子(字面上)你可以这样做:
如果你想要“从[一旦生成] 生成器中只获取一个元素”(我想 50% 就是这样最初的意图,也是最常见的意图)然后:
这样可以避免显式使用
generator.next()
,并且输入结束处理不需要(神秘的)StopIteration
异常处理或额外的默认值比较。仅当您想在生成器结束时执行一些特殊操作时,才需要
for
语句部分的else:
。关于
next()
/.next()
的注意事项:在 Python3 中,
.next()
方法已重命名为.__next__()
有充分的理由:它被认为是低级别的(PEP 3114)。在 Python 2.6 之前,内置函数next()
不存在。甚至讨论了将next()
移至operator
模块(这本来是明智的),因为它的需求很少且内置名称的膨胀值得怀疑。在没有默认值的情况下使用
next()
仍然是非常低级的做法 - 在正常应用程序代码中像晴天霹雳一样公开抛出神秘的StopIteration
。并且将next()
与默认哨兵一起使用 - 这最好应该是直接在builtins
中使用next()
的唯一选项 - 是有限的,而且经常给出了奇怪的非Python逻辑/可读性的理由。底线:使用 next() 应该很少 - 就像使用
operator
模块的函数一样。使用for x in iterator
、islice
、list(iterator)
和其他无缝接受迭代器的函数是在应用程序级别使用迭代器的自然方式- 而且总是有可能的。next()
是低级的,一个额外的概念,不明显 - 正如该线程的问题所示。例如,在for
中使用break
是常规做法。For picking just one element of a generator use
break
in afor
statement, orlist(itertools.islice(gen, 1))
According to your example (literally) you can do something like:
If you want "get just one element from the [once generated] generator whenever I like" (I suppose 50% thats the original intention, and the most common intention) then:
This way explicit use of
generator.next()
can be avoided, and end-of-input handling doesn't require (cryptic)StopIteration
exception handling or extra default value comparisons.The
else:
offor
statement section is only needed if you want do something special in case of end-of-generator.Note on
next()
/.next()
:In Python3 the
.next()
method was renamed to.__next__()
for good reason: its considered low-level (PEP 3114). Before Python 2.6 the builtin functionnext()
did not exist. And it was even discussed to movenext()
to theoperator
module (which would have been wise), because of its rare need and questionable inflation of builtin names.Using
next()
without default is still very low-level practice - throwing the crypticStopIteration
like a bolt out of the blue in normal application code openly. And usingnext()
with default sentinel - which best should be the only option for anext()
directly inbuiltins
- is limited and often gives reason to odd non-pythonic logic/readablity.Bottom line: Using next() should be very rare - like using functions of
operator
module. Usingfor x in iterator
,islice
,list(iterator)
and other functions accepting an iterator seamlessly is the natural way of using iterators on application level - and quite always possible.next()
is low-level, an extra concept, unobvious - as the question of this thread shows. While e.g. usingbreak
infor
is conventional.Generator 是一个生成迭代器的函数。因此,一旦有了迭代器实例,请使用 next() 来获取迭代器中的下一个项目。
例如,使用 next() 函数获取第一个项目,然后使用
for in
处理剩余项目:Generator is a function that produces an iterator. Therefore, once you have iterator instance, use next() to fetch the next item from the iterator.
As an example, use next() function to fetch the first item, and later use
for in
to process remaining items:您可以使用解构来选择特定项目,例如:
请注意,这将消耗您的生成器,因此虽然可读性很高,但它的效率低于
next()
之类的东西,并且对无限生成器来说是毁灭性的:You can pick specific items using destructuring, e.g.:
Note that this is going to consume your generator, so while highly readable, it is less efficient than something like
next()
, and ruinous on infinite generators:我不相信有一种方便的方法可以从生成器中检索任意值。生成器将提供 next() 方法来遍历自身,但不会立即生成完整序列以节省内存。这就是生成器和列表之间的功能差异。
I don't believe there's a convenient way to retrieve an arbitrary value from a generator. The generator will provide a next() method to traverse itself, but the full sequence is not produced immediately to save memory. That's the functional difference between a generator and a list.
确保捕获最后一个元素被获取后抛出的异常
make sure to catch the exception thrown after the last element is taken
对于那些浏览这些答案以获取 Python3 的完整工作示例的人来说...好吧,你可以:
输出:
For those of you scanning through these answers for a complete working example for Python3... well here ya go:
This outputs:
这是从迭代器获取单个对象的简短示例。如果您知道您要查找的对象的属性或属性,则会将其提供给您。
This is a short example of getting a single object from an iterator. If you know the attribute, or property of the object your looking for this will give it to you.
我相信唯一的方法是从迭代器获取列表,然后从该列表中获取所需的元素。
I believe the only way is to get a list from the iterator then get the element you want from that list.