问题:如何从生成器中仅选择一项(在python中)?
我有一个类似下面的生成器函数:
def myfunct():
...
yield result
调用此函数的常用方法是:
for r in myfunct():
dostuff(r)
我的问题是,有什么方法可以随时从生成器中获取一个元素吗?例如,我想做类似的事情:
while True:
...
if something:
my_element = pick_just_one_element(myfunct())
dostuff(my_element)
...
回答 0
使用创建一个生成器
g = myfunct()
每当您想要一个项目时,请使用
next(g)
(或g.next()
在Python 2.5或更低版本中)。
如果生成器退出,它将升高StopIteration
。您可以根据需要捕获此异常,也可以将default
参数用于next()
:
next(g, default_value)
回答 1
要仅选择生成器的一个元素,请break
在for
语句中使用,或list(itertools.islice(gen, 1))
根据您的示例(从字面上看),您可以执行以下操作:
while True:
...
if something:
for my_element in myfunct():
dostuff(my_element)
break
else:
do_generator_empty()
如果您想“ 每当我喜欢的时候就从 [生成的] 生成器中仅获取一个元素 ”(我想是最初意图的50%,也是最常见的意图),那么:
gen = myfunct()
while True:
...
if something:
for my_element in gen:
dostuff(my_element)
break
else:
do_generator_empty()
这样generator.next()
可以避免显式使用,并且输入结束处理不需要(神秘的)StopIteration
异常处理或额外的默认值比较。
在else:
的for
,如果你想要做一些特别的结束产生的case语句段时,才需要。
注意上next()
/ .next()
:
在Python3中,该.next()
方法被重命名.__next__()
为有充分的理由:它被认为是低级的(PEP 3114)。在Python 2.6之前,内置函数next()
不存在。甚至讨论过迁移next()
到该operator
模块(这本来是明智的做法),因为它很少需要,并且内置名称的可疑膨胀。
在next()
没有默认值的情况下使用仍然是非常低级的实践- StopIteration
在普通的应用程序代码中公开地将神秘的东西扔掉。而且使用next()
默认的哨兵-最好是next()
直接输入的唯一选择builtins
-受限制,并且通常会给出奇怪的非Python逻辑/可读性的原因。
底线:很少使用next()-就像使用operator
模块的功能一样。使用for x in iterator
,islice
,list(iterator)
等功能接受一个迭代器无缝地使用是在应用层上的迭代器的自然方式-而且相当总是可能的。next()
是低级的,一个额外的概念,很明显-正如该线程的问题所示。虽然例如,使用break
在for
是常规的。
回答 2
我不认为有一种便捷的方法可以从生成器中检索任意值。生成器将提供next()方法来遍历自身,但是不会立即生成完整序列以节省内存。那就是生成器和列表之间的功能差异。
回答 3
对于那些浏览这些答案的人来说,它们是Python3的完整工作示例…在这里,您可以继续:
def numgen():
x = 1000
while True:
x += 1
yield x
nums = numgen() # because it must be the _same_ generator
for n in range(3):
numnext = next(nums)
print(numnext)
输出:
1001
1002
1003
回答 4
Generator是产生迭代器的函数。因此,一旦有了迭代器实例,就可以使用next()从迭代器中获取下一项。例如,使用next()函数来获取第一个项目,然后for in
用于处理剩余的项目:
# create new instance of iterator by calling a generator function
items = generator_function()
# fetch and print first item
first = next(items)
print('first item:', first)
# process remaining items:
for item in items:
print('next item:', item)
回答 5
generator = myfunct()
while True:
my_element = generator.next()
确保捕获采用最后一个元素后引发的异常
回答 6
我相信唯一的方法是从迭代器中获取一个列表,然后从该列表中获取所需的元素。
l = list(myfunct())
l[4]