【问题标题】:Python for loop range function causing an infinite loopPython for循环范围函数导致无限循环
【发布时间】:2019-05-06 13:06:07
【问题描述】:

我正在构建一个数独函数来学习如何在 python 中编码。我似乎正在使用 for 循环创建一个无限循环,但我不明白如何。该代码尝试查看数独板的每个空方格,并检查数独规则是否允许值 counter。如果计数器被允许,则板被更新并且函数移动到下一个空方格。如果不允许使用计数器,则计数器会增加 1 并再次测试。

当计数器大于 9 时,我遇到了问题。发生这种情况时,我想查看原始板上的前一个空方格(名为拼图)并删除该方格中的值。该函数应该设置计数器等于前一个方块中的值 +1 并调用自身再次运行。

本质上,该函数正在测试每个空方格的可能值,直到找到一个值,然后移动到下一个方格。如果没有可能的值,该函数将回溯,删除最后一个方块并再次尝试运行。

当计数器大于 9 时,我的问题似乎发生在 else 条件下。这部分函数导致无限循环,反复打印出“否”。

我假设我的函数卡在 while 循环中,但我不确定为什么。

puzzleBoard =[[1,2,3,4,5,6,7,8,9],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]]


def solvePuzzle():

#start by looking at each square in the 9x9 sudoku grid and check if that square is empty (=0)
for i in range(9):
    for j in range(9):
        counter = 1
        topX = 3*(i//3)
        topY = 3*(j//3)

        # while the board at index [i][j] is empty check if the value of 'counter' fits in the square and adheres to the sudoku rules
        # if counter is not an allowed value increment counter by 1 and try again
        while puzzleBoard[i][j] ==0:
            if counter < 10:
                row = all([counter != puzzleBoard[i][x] for x in range(9)])
                column = all([counter != puzzleBoard[y][j] for y in range(9)])
                box = all([counter != puzzleBoard[x][y] for x in range(topX, topX+3) for y in range(topY, topY+3)])

                if row and column and box == True:
                    puzzleBoard[i][j]=counter
                    uploadBoard()
                else:
                    counter = counter + 1

            # if counter is larger than ten set the previous square ([i][j-1]) equal to zero, set the counter equal to one more than the previous squares value, and call the solvePuzzle function again.
            else:
                for k in range(i,0,-1):
                    for l in range(j-1,0,-1):
                        if puzzle[k][l]==0:
                            counter = puzzleBoard[k][l] + 1
                            puzzleBoard[k][l]=0
                            solvePuzzle()
                            return
                        else:
                            print("no")

【问题讨论】:

  • 给我们一个puzzleBoard的例子?
  • 对于您的print("no"),您能否将其设为print(f"i={i}, j={j}, k={k}, l={l}",以便我们确认它粘在哪里。这应该让您看到它要么无限期地循环回其中一个,要么它正在增长但循环非常长。
  • 你能添加一个uploadBoard的例子吗?我现在坚持...
  • ...如果puzzle 发起,在哪里?如果像if puzzle[k][l]==0: 这样的行要执行任何操作,则需要在某处定义puzzle
  • @cardamom 很抱歉没有说清楚,但最初是拼图=拼图板。

标签: python for-loop while-loop


【解决方案1】:

我能够得出答案。代码有一些问题,但主要问题是在较低的else 语句counter = puzzleBoard[k][l] + 1 中,然后再次调用该函数,这会将变量counter 重置为1。

我能够通过创建一个全局变量 countholder 并将 else 语句修改为 countholder = puzzleBoard[k][l] + 1 来解决这个问题

完整的工作代码如下所示:

puzzleBoard =[[0,2,0,0,0,0,0,0,0],[0,0,0,6,0,0,0,0,3],
              [0,7,4,0,8,0,0,0,0],[0,0,0,0,0,3,0,0,2],
              [0,8,0,0,4,0,0,1,0],[6,0,0,5,0,0,0,0,0],
              [0,0,0,0,1,0,7,8,0],[5,0,0,0,0,9,0,0,0],
              [0,0,0,0,0,0,0,4,0]]

puzzle =[[0,2,0,0,0,0,0,0,0],[0,0,0,6,0,0,0,0,3],
              [0,7,4,0,8,0,0,0,0],[0,0,0,0,0,3,0,0,2],
              [0,8,0,0,4,0,0,1,0],[6,0,0,5,0,0,0,0,0],
              [0,0,0,0,1,0,7,8,0],[5,0,0,0,0,9,0,0,0],
              [0,0,0,0,0,0,0,4,0]]

countholder = 1

def solvePuzzle():

    #start by looking at each square in the 9x9 sudoku grid and check if that square is empty (=0)
    for i in range(9):
        for j in range(9):
            global countholder
            counter = countholder
            topX = 3*(i//3)
            topY = 3*(j//3)

            # while the board at index [i][j] is empty check if the value of 'counter' fits in the square and adheres to the sudoku rules
            # if counter is not an allowed value increment counter by 1 and try again
            while puzzleBoard[i][j] ==0:
                if counter < 10:
                    row = all([counter != puzzleBoard[i][x] for x in range(9)])
                    column = all([counter != puzzleBoard[y][j] for y in range(9)])
                    box = all([counter != puzzleBoard[x][y] for x in range(topX, topX+3) for y in range(topY, topY+3)])

                    if (row and column and box) == True:
                        puzzleBoard[i][j]=counter
                        print(puzzleBoard)
                        countholder = 1
                    else:
                        counter = counter + 1

                # if counter is larger than ten set the previous square ([i][j-1]) equal to zero, set the counter equal to one more than the previous squares value, and call the solvePuzzle function again.
                else:
                    run_One = True         
                    for k in range(i,-1,-1):
                        if run_One == True:
                            run_One = False
                            for l in range(j,0,-1):
                                if l == 0:
                                    print(run_One)
                                elif puzzle[k][l-1]==0:
                                    countholder = puzzleBoard[k][l-1] + 1
                                    puzzleBoard[k][l-1]=0
                                    solvePuzzle()
                                    return
                                else:
                                    continue
                        else:
                            for l in range(8,-1,-1):
                                if puzzle[k][l]==0:
                                    countholder = puzzleBoard[k][l] + 1
                                    puzzleBoard[k][l]=0
                                    solvePuzzle()
                                    return
                                else:
                                    continue

solvePuzzle()   

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多