当我使用以下语句在 Python 控制台上执行以下代码时,
for L in permute([12, 32, 3]):
print(L)
对于下面的代码,
def permute(L):
if len(L) <= 1:
yield L
else:
for i in range(0, len(L)):
L[0], L[i] = L[i], L[0]
for L1 in permute(L[1:]):
yield [L[0]] + L1
每个结果仅出现一次。但是,如果我删除 else
并删除其下方代码的关联缩进,我会收到每个结果两次。
为什么会发生这种情况?
最佳答案
来自docs :
The big difference between
yield
and areturn
statement is that on reaching ayield
the generator’s state of execution is suspended and local variables are preserved. On the next call to the generator’s__next__()
method, the function will resume executing.
发生这种情况是因为 if
主体不会中断执行,因此它会前进到下一个 yield
语句,并且 with else
子句到达函数结束并隐式返回。
检查
def counter(step):
assert step >= 0, ('Can count only from non-negative number, but found '
+ str(step))
if step == 0:
print('Reached end')
yield step
print('Step', step)
for sub_step in counter(step - 1):
yield sub_step
>>> list(counter(1))
Step 1
Reached end
Traceback (most recent call last):
File "<input>", line 13, in <module>
Step 0
File "<input>", line 8, in counter
File "<input>", line 8, in counter
File "<input>", line 3, in counter
AssertionError: Can count only from non-negative number, but found -1
和
def counter(step):
assert step >= 0, ('Can count only from non-negative number, but found '
+ str(step))
if step == 0:
print('Reached end')
yield step
else:
print('Step', step)
for sub_step in counter(step - 1):
yield sub_step
# implicitly returns here
>>> list(counter(1))
Step 1
Reached end
正如我们所见,如果没有else
,执行将继续并调用counter
,step
等于-1
。
因此,您可以保留 else
或重构您的 if
子句,并在其中添加 return
语句以显式完成执行,例如
def permute(L):
if len(L) <= 1:
yield L
return
for i in range(0, len(L)):
L[0], L[i] = L[i], L[0]
for L1 in permute(L[1:]):
yield [L[0]] + L1
进一步阅读
- Generators .
-
return
和yield
声明。
关于python - 为什么删除 else 会导致递归函数重复结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50365163/