def getBlocks(board):
answer = []
for r,c in itertools.product(range(3), repeat=2):
answer.append([board[r+i][c+j] for i,j in itertools.product(range(0, 9, 3), repeat=2)])
return answer
Of course, you could replace the whole thing with just one list comprehension:
answer = [[board[r+i][c+j] for i,j in itertools.product(range(0, 9, 3), repeat=2)]
for r,c in itertools.product(range(3), repeat=2)]
In case you are interested in a version that doesn't use any built-ins to do any heavy lifting:
def getBlocks(board):
answer = []
for r in range(3):
for c in range(3):
block = []
for i in range(3):
for j in range(3):
block.append(board[3*r + i][3*c + j])
answer.append(block)
return answer
So what's happening here?:
Well, first, we decide to iterate over the 9 blocks that we want. These are governed by the r
and c
variables. This is also why we multiply them by 3 when we access the numbers on the board (because each block is a square of side 3).
Next, we want to iterate over the elements in each block. Translation: Lookup the numbers within each 3x3 block. The index of each element within the block is governed by i
and j
. So we have i
and j
that govern the elements we want to access, along with r
and c
, which are their offsets from the board itself, determining the location of the "block" we want. Now we're off to the races.
For each r
and c
(notice that each loops over range(3)
, so there are 9 (r,c)
pairs - the 9 blocks that we are after), loop over the 9 elements in the block (the 9 (i,j)
pairs). Now, simply access the elements based on their relative locations from the (r,c)
offsets (3*r
gives the first row of the relevant block, and adding i
gives the row of the required element. Similarly, 3*c
gives the first column of the relevant block, and adding j
gives the column of the required element. Thus, we have the coordinates of the element we want). Now, we add the element to block
.
Once we've looped over all the elements in the block, we add the block itself to the answer, and presto! we're done