当我使用以下语句在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
并删除其下方代码的相关缩进,我会收到两次结果。
为什么会这样?
答案 0 :(得分:1)
来自docs:
yield
和return
语句之间的最大区别在于,在达到yield
时,生成器的执行状态将被暂停,并保留局部变量。在下次调用生成器的__next__()
方法时,该函数将继续执行。
所以发生这种情况是因为if
正文不会中断执行,因此它会向前移动到下一个yield
语句,并且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
return
和yield
声明。答案 1 :(得分:0)
因为你yield
两次,如果没有else
循环。