Read a book see iterators and generators, the general use is not a problem, but many times it is not used to be used to
The book in the example of the classic eight Queen question, as a programmer how to let go of the opportunity to do the problem, and then first himself, so with the following this ugly code
deftable (M, LST):" "draw a chessboard of M-columns with a queen flag in each row" "Head='┌'+'─┬'* (m-1) +'─┐'Row=LambdaX:'│'+'│'* x +'╳│'+'│'* (M-x-1) Trow='├'+'─┼'* (m-1) +'─┤'Tail='└'+'─┴'* (m-1) +'─┘' Print(head) forI, ninchZip (range (len (LST)), LST):Print(Row (n))Print(Trow)ifI < Len (LST)-1Else Print(tail) Queens= [0]*8defRightqueen (LST, m):" "determine if all the queens of LST are interfering with the m position of the next line queen, and return true if not interfering" " forI, ninchZip (range (len (LST)), LST):if(n = = morLen (LST)-i = = M-norLen (LST)-i = = N-m):returnFalsereturnTruedefCalqueen (LST, n):" "solving the nth queen without interfering with the former queen if the nth row succeeds, the n+1 row is solved, otherwise the n-1 line is solved and the n row is reset" " forIinchRange (Lst[n], 8): ifRightqueen (lst[:n], i): Lst[n]=I calqueen.count+ = 1Print(Calqueen.count) Table (8, Lst[:n+1]) ifN < 7:calqueen (LST, n+1) Break Else: #If there is still no solution after traversing 8, the previous row is re-solvedLst[n] =0 Lst[n-1] + = 1Print('solve the previous row') Calqueen (LST, n-1) Calqueen.count=0 Calqueen (Queens, 0)
The previous table function is only used to draw the board, after writing it feels like Python is really a very concise language, of course, can be more concise, and now my Code style still retains a strong C language style, this transformation is estimated to take some time
That he ugly not because he didn't use iterators, the main problem is that the two branches of the function use iterations, only the eighth level will end the iteration, the code iterations to reach more than 100 times, so many iterations of its memory consumption and operational efficiency is not very good
Therefore, the modified version of the code should be in the failure to return the results of the run to reduce the number of iterations, the adjusted code is as follows:
deftable (M, LST):" "draw a chessboard of M-columns with a queen flag in each row" "Head='┌'+'─┬'* (m-1) +'─┐'Row=LambdaX:'│'+'│'* x +'╳│'+'│'* (M-x-1) Trow='├'+'─┼'* (m-1) +'─┤'Tail='└'+'─┴'* (m-1) +'─┘' Print(head) forI, ninchZip (range (len (LST)), LST):Print(Row (n))Print(Trow)ifI < Len (LST)-1Else Print(tail) Queens= [0]*8defRightqueen (LST, m):" "determine if all the queens of LST are interfering with the m position of the next line queen, and return true if not interfering" " forI, ninchZip (range (len (LST)), LST):if(n = = morLen (LST)-i = = M-norLen (LST)-i = = N-m):returnFalsereturnTruedefCalqueen (LST, n):" "solving the nth queen without interfering with the former queen if the nth row succeeds, the n+1 row is solved, otherwise the n-1 line is solved and the n row is reset" " forIinchRange (8): ifRightqueen (lst[:n], i): Lst[n]=I calqueen.count+ = 1Print(Calqueen.count) Table (8, Lst[:n+1]) ifN < 7: if notCalqueen (LST, n+1):Continue returnTrueElse: #If there is still no solution after traversing 8, the previous row is re-solved Print('solve the previous row') Calqueen.count-= 1returnFalsecalqueen.count=0 Calqueen (Queens, 0)
After reducing the number of iterations at least the program is reasonable, but after looking at the use of the generator, iterator code still feel that I feel too little about Python and the iterator programming, in order to enhance the feeling, close the book according to their own understanding and blind write again, of course, the code is not quite consistent with the books, but the idea of the same
deftable (M, LST):" "draw a chessboard of M-columns with a queen flag in each row" "Head='┌'+'─┬'* (m-1) +'─┐'Row=LambdaX:'│'+'│'* x +'╳│'+'│'* (M-x-1) Trow='├'+'─┼'* (m-1) +'─┤'Tail='└'+'─┴'* (m-1) +'─┘' Print(head) forI, ninchZip (range (len (LST)), LST):Print(Row (n))Print(Trow)ifI < Len (LST)-1Else Print(tail)defRightqueen (LST, m):" "determine if all the queens of LST are interfering with the m position of the next line queen, and return true if not interfering" " forI, ninchZip (range (len (LST)), LST):if(n-minch(0, Len (LST)-I, I-Len (LST )):returnFalsereturnTruedefCalqueen (LST, n):" "solving the nth queen with the previous Queen does not interfere with the submission of data only on the eighth level, each of the remaining layers is the addition of all possible and subsequent additions to this layer" " forIinchRange (8): Calqueen.total+ = 1ifRightqueen (LST, i): Calqueen.count+ = 1ifn = = 7: Calqueen.number+ = 1Print(Calqueen.number, Calqueen.count, Calqueen.total)yieldLST +[i]Else: forLinchCalqueen (LST + [i], n + 1): yieldLcalqueen.total=0calqueen.count=0calqueen.number=0 forLinchCalqueen ([], 0): Table (8, L)
In fact, the core code of two functions is only 13 lines, using in and tuples instead of 3 conditional judgments, using iterators instead of the function return value judgment, because if the iterator is empty, then the upper call function traversal will fail, automatically solves the problem of my original algorithm
And this program can traverse 92 of the eight Queens solution, although my previous code changes should also be possible, but there is no such a simplification
Because of the presence of generators, the iterators are very convenient to use, and in the latter case, the way of the generators and iterators should be given precedence when dealing with some methods that need to iterate through the layers.
Python Learning II (generator and eight Queens algorithm)