This approach is pretty much the same as others but I've chosen to use positive/negative to "encode" additional information. Nice thing about this is that you can use mod operator which only cares about the absolute values. I also handle my bounds a bit differently than most.
def gameOfLife(self, board): """ :type board: List[List[int]] :rtype: void Do not return anything, modify board in-place instead. """ num_rows, num_cols = len(board), len(board) for r in range(num_rows): is_firstr = not r is_lastr = (r == num_rows-1) for c in range(num_cols): is_firstc = not c is_lastc = (c == num_cols-1) # Inclusive bounds. rstart, rend = r-1, r+1 cstart, cend = c-1, c+1 # Update bounds if we are on edge. if is_firstr: rstart = r if is_lastr: rend = num_rows-1 if is_firstc: cstart = c if is_lastc: cend = num_cols-1 # If a cell is 0, and it needs to live, assign -1. # If a cell is 0, and it needs to remain dead, assign -2. # If a cell is 1, and it needs to die, assign 2. # If a cell is 1, and it needs to remain live, assign 1. total_live = 0 for ir in range(rstart, rend+1): total_live += sum(1 if x > 0 else 0 for x in board[ir][cstart:cend+1]) # Check current cell value and assign new value. if board[r][c]: # Previously summed 3x3 block but current cell needs to be omitted. total_live -= 1 if total_live < 2 or total_live > 3: board[r][c] = 2 else: board[r][c] = 1 else: if total_live == 3: board[r][c] = -1 else: board[r][c] = -2 # Normalize to 1s and 0s. for r in range(num_rows): for c in range(num_cols): if board[r][c] % 2: board[r][c] = 1 else: board[r][c] = 0