Search code examples
python-3.xlistindexingnested-loopstic-tac-toe

Finding ALL indexes of elements in nested List


Tic tac toe where the board is represented as [['x', 'x', 'x'], [' ', ' ', ' '], [' ', ' ', ' ']]

we would like to identify all the empty squares on board. The empty square locations on the board will be returned as a (row, column) tuple.

Complete the function empty_squares(board), which returns the list of tuples, where each tuple is the (row, column) of the empty square.

This is what i have so far, it returns the tuples of all squares but i only want the empty ones.

def empty_squares(board):
    check = ' '
    target_cell_list = []
    for i in range(len(board)):
        for j in range(len(board[i])):
            target_cell_list.append((i, j))
    return target_cell_list

Solution

  • You can slightly change your approach to make it more "pythonic". Avoiding nested for-loops you can use list comprehension with built-in enumerate statement. So empty_sqares can look like this:

    def empty_sqares(board):
        return [(row_idx, col_idx) for row_idx, row in enumerate(board)
                for col_idx, item in enumerate(row) if item == ' ']
    

    Most important think to figure out is what enumerate does. In short it iterates through iterable (ex. list, list of lists, lists of objects etc.) and for each element returns a tuple containing a count (from start which defaults to 0) and the values obtained from iterating over iterable. Source: https://docs.python.org/3/library/functions.html#enumerate

    So what is going on in code:

    • for row_idx, row in enumerate(board) iterate through rows in board. Because items of board (rows) are lists, consecutive results of enumerate(board) are row index (row_idx) and row content (row which is list of strings). So for for example, first "iteration" result of enumerate(board) will be: row_idx = 0 row = ['x', 'x', 'x'].
    • for col_idx, item in enumerate(row) iterate through row, pick each element of a row and assign it to item. So for example, first "iteration" result of enumerate(row) will be: col_idx = 0 item = 'x'.
    • if item == ' ' performs check if picked character (in your case you have two options'x'' or ' ') equals single space ...
    • ... and if check is true, tuple (row_idx, col_idx) is formed.
    • Whole thing is enclosed inside square brackets [..] to make list of tuples. But remember, new tuple is appended to result only if above condition is met.