Python: How to access a diagonal in reverse in a matrix?

Viewed 130

I am trying to create a tic tac toe program, and I need to return a diagonal in a 3x3 matrix.

Say my board looks like this:

board = [
    ["a", "x", "b"],
    ["c", "o", "d"],
    ["e", "f", "g"]
]

I have for the forward matrix:

diag = [board[i][i] for i in range(len(board))]

which returns:

>>> diagonal(board, 1)
['a', 'o', 'g']

(If possible can someone explain to me why this works. I'm not so good with comprehending lists...).

How would I go about getting the reverse? say, ['b', 'o', 'e']?

Thank you!

3 Answers

Your board is a list that contains three items, which are also lists. Therefore, i will iterate from 0 to 2 inclusive. By calling board[i][i], you are calling three commands: board[0][0], board[1][1], board[2][2]. In a basic 1D list, board[0] will refer to the first element, board[1] to the second, etc. With your 2D array, in the command board[0][0], you are calling the first element of the first element of the board (so basically "a"). Next, you are moving to the right one step and the bottom one step, and you are calling the second element of the second element of the board ("o"). This is the logic behind the code.

To get the other diagonal, you have to use:

diag = [board[i][len(board) - 1 - i] for i in range(len(board))]

This means instead of calling board[0][0], you are calling board[0][3 - 1 - 0], which is board[0][2]. The next iteration will call board[1][1], and the next board[2][0]. You first subtract 1 from the length, because length counting starts from 1 (e.g., there are three elements in your board, len(board) = 3), while indexing starts at 0 (board[0][3] does not exist, only board[0][0], board[0][1], and board[0][2]). Hope this helps!

Your row will increment as 1st case only. Only the column indexing will change. you will start from end and move towards left by decrementing it.

For forward diagonal: You are taking the location where your (row_index==col_index) => (0,0) , (1,1), (2,2)

For Reverse: start with the end and move towards left side.

Try:

diag = [board[i][len(board)-1-i] for i in range(len(board))]

['b', 'o', 'e']

Inorder to get diagonal elements you can do the following.

For leading diagonal :

leading_diagonal = [ row[i] for i,row in enumerate(board) ]

For counter diagonal:

counter_diagonal = [ row[-i-1] for i,row in enumerate(board) ]

In above approach it goes through each row counting its index at i and takes row[i] which is true as for 0th row, the element will be 0 and so on. For counter diagonal, it takes row[-i-1] where -i-1 is -(i+1). In Python list - actually means to take element from last.

Other solution is by using lambda and map function :

For leading diagonal :

leading_diagonal = list(map(lambda x: x[board.index(x)], board))

For counter diagonal:

counter_diagonal = list(map(lambda x: x[(len(board) - 1) - board.index(x)], board))

Related