Python 由递归辅助函数生成
我想从递归函数(下面的代码)中得到结果,但是很难让输出与我想要的匹配。理想情况下,如果我打电话Python 由递归辅助函数生成,python,Python,我想从递归函数(下面的代码)中得到结果,但是很难让输出与我想要的匹配。理想情况下,如果我打电话 print(列表(n_queens_解决方案(4))) 我会明白的 [[1,3,0,2],[2,0,3,1]] 但是函数返回 [],[] 我不太熟悉Python生成器;我尝试过各种“收益”和“回报”的排列,但都没有用 def n_queens_有效(板): 对于范围内的q1(透镜(板)): 对于范围内的q2(1,透镜(板)-q1): 如果板[q1]==板[q1+q2]或板[q1+q2]==板[q
print(列表(n_queens_解决方案(4)))
我会明白的
[[1,3,0,2],[2,0,3,1]]
但是函数返回
[],[]
我不太熟悉Python生成器;我尝试过各种“收益”和“回报”的排列,但都没有用
def n_queens_有效(板):
对于范围内的q1(透镜(板)):
对于范围内的q2(1,透镜(板)-q1):
如果板[q1]==板[q1+q2]或板[q1+q2]==板[q1]+q2或板[q1+q2]==板[q1]-q2:
返回错误
返回真值
def n_queens_解决方案(n):
董事会=[]
返回n皇后助手(0,板,n)
def n_queens_辅助对象(n、板、大小):
如果透镜(板)=尺寸:
印刷(电路板)
屈服板
其他:
对于范围内的i(尺寸):
董事会附件(一)
如果n_queens_有效(董事会):
n皇后助手的收益率(n+1,板,大小)
board.pop()
打印(列表(n_queens_解决方案(4)))
上面代码中最后一行的打印应该输出:[[1,3,0,2],[2,0,3,1]],但返回[[],[]。是的,您需要学习有关生成器的教程,以更全面地了解它们的工作原理。您目前面临的问题是
n_queens\u solutions
只调用helper
函数一次——第一个分支无法找到解决方案,并且您正在显示失败时返回的空板
简单地说,将生成器视为带有书签的函数。当您调用生成器时,它将一直执行,直到到达第一个屈服点;它返回该值,但保留其所有状态信息:所有变量值、它在代码中的位置等。当您再次调用它时,它将从该点重新启动,并一直持续到下一个屈服
,以这种方式继续,直到它从代码末尾脱落
生成器最简单的用途是作为一种迭代器:
for solution in n_queens_helper(...):
您已经以这种方式使用了它(通过在主程序中构建解决方案列表)和重复使用部分解决方案(使用yield from
),但是您需要在控制流上做更多的工作。尝试插入跟踪语句:
def n_queens_helper(n, board, size):
print("ENTER helper", n, board)
if len(board) == size:
现在观察执行过程。让我们用一个更简单的例子来说明发生了什么:
def my_func():
output = [1,2,3]
print("Output", output)
yield output
print("Let's now clear the output")
output.clear()
print("Cleared output", output)
result = my_func()
print("Result", result)
print("Result List", list(result))
输出:
Result <generator object my_func at 0x7fd7ccc2a6d0>
Output [1, 2, 3]
Let's now clear the output
Cleared output []
Result List [[]]
结果
输出[1,2,3]
现在让我们清除输出
清除输出[]
结果列表[]]
- 当调用函数本身(输出的第一行)时,实际上不执行生成器函数中的任何内容
- 当我们从生成器获取所有内容时(通过调用
list(result)
),我们运行生成器直到它到达函数的末尾,将所有yield
结果放入列表中
- 如我们所见,由于函数中的所有内容现在都已执行,因此也将执行
output.clear()
方法
结果
变量的内容与生成器函数末尾的输出
变量的内容匹配
为了防止这种行为,一个简单的解决方案是返回我们正在返回的值的副本,以便我们以后可以对其进行操作:产生输出[:]
(虽然这是一个浅拷贝)我想这可能是因为您通过了相同的板。创建列表时,所有的append
和pop
最终只在一个board
对象上执行。尝试在递归中传递副本(例如,board[:]
)@njzk2啊,这很有意义!我试过你的建议,它奏效了。谢谢你的帮助!