gpt4 book ai didi

python - python 生成器中的代码何时停止执行?

转载 作者:太空宇宙 更新时间:2023-11-03 14:44:27 26 4
gpt4 key购买 nike

我试图通过构建一个行为类似于“enumerate”内置函数的生成器来理解 yield 语句的行为,但我发现不一致取决于我如何遍历它。

def enumerate(sequence, start=0):
n = start
for elem in sequence:
print("Before the 'yield' statement in the generator, n = {}".format(n))
yield n, elem
n += 1
print("After the 'yield' statement in the generator, n = {}".format(n))

我对生成器的理解是,一旦达到 yield 语句,代码的执行就会停止,并返回一个值。这与我通过下面的脚本得到的结果相符。

a = 'foo'
b = enumerate(a)
n1,v1 = next(b)
print('n1 = {}, v1 = {}\n'.format(n1,v1))
n2,v2 = next(b)
print('n2 = {}, v2 = {}'.format(n2,v2))

在这种情况下,生成器似乎恰好在 yield 语句处停止,并在 n+=1 处继续执行第二个“下一个”语句:

Before the 'yield' statement in the generator, n = 0
n1 = 0, v1 = f

After the 'yield' statement in the generator, n = 1
Before the 'yield' statement in the generator, n = 1
n2 = 1, v2 = o

但是,如果我使用下面的 for 循环,生成器似乎不会在 yield 语句处停止。

for n,v in enumerate(a[0:1]):
print('n = {}, v = {}'.format(n,v))

这是我得到的:

Before the 'yield' statement in the generator, n = 0
n = 0, v = f
After the 'yield' statement in the generator, n = 1

考虑评论进行编辑

我意识到我只迭代了一个元素,但我没想到会看到最后一句“在生成器中的‘yield’语句之后”(即使我迭代了所有元素,它也会出现。

print('\n\n')
for n,v in enumerate(a):
print('n = {}, v = {}'.format(n,v))

Before the 'yield' statement in the generator, n = 0
n = 0, v = f
After the 'yield' statement in the generator, n = 1
Before the 'yield' statement in the generator, n = 1
n = 1, v = o
After the 'yield' statement in the generator, n = 2
Before the 'yield' statement in the generator, n = 2
n = 2, v = o
After the 'yield' statement in the generator, n = 3

为什么会这样?

最佳答案

这里的根本问题是,您混淆了一个事实,即仅通过查看就知道生成器何时会耗尽,而 Python 只能通过运行代码才能知道。当 Python 到达 yield你认为是最后一个,它实际上并不知道它是最后一个。如果您的生成器看起来像这样怎么办:

def enumeratex(x, start=0):
for elem in x:
yield start, x
start += 1
yield start, None

在这里,出于无人知晓的原因,最后一个 None元素在主生成器循环之后返回。 Python 将无法知道生成器已完成,直到您要么

  1. 从发电机返回。
  2. 提出一个错误,在这种情况下一切都会停止。

在 Python 3.7 之前的版本中,生成器可以引发 StopIteration来表示终止。事实上,return 语句相当于 raise StopIteration (如果返回 None )或 raise StopIteration(return_value) .

因此,虽然您告诉 Python 结束生成器的确切方式取决于您,但您必须明确说明。 yield本身并不会结束生成器。

长话短说

生成器循环中的所有代码将始终运行,即使在生成最后一个值之后也是如此,因为 Python 只能通过实际执行所有代码才能知道它是最后一个值。

关于python - python 生成器中的代码何时停止执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50911425/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com