Question: Few days ago I found the next example of howto implement customs list classes via subclassing the MutableSequence from collections.abc. class TypedList(MutableSequence): def __init__(self, oktypes, *args): self.oktypes = oktypes self.list = list() self.extend(list(args)) def check(self, v): if not isinstance(v, self.oktypes): raise TypeError(v) def __len__(self): return len(self.list) def __getitem__(self, i): return self.list[i] def __delitem__(self, i): del self.list[i] def __setitem__(self, i, v): self.check(v) self.list[i] = v def insert(self, i, v): self.check(v) self.list.insert(i, v) def __str__(self): return str(self.list)  Example of use of TypedList:  tl = TypedList(int) # ok tl.append(1) # next TypeError will be raised tl.append('1')  My Question: I was wondering if there is way of implementing an two-dimensions SudokuArray(MutableSequence) class in similar manner for mananing a sudoku array in a game? For giving you an idea, below you can see a possible implementation (non-operative) of that SudokuArray(MutableSequence): class SudokuArray(MutableSequence): def __init__(self, n_rows=9, n_columns=9, init_value=None): self.n_rows = n_rows self.n_columns = n_columns self.array = [[init_value for _ in range(0, self.n_columns, 1)] for _ in range(0, self.n_rows, 1)] def check(self, row_number, column_number, number): if number in self.get_row_values(row_number) or number in self.get_column_values(column_number) or number in self.get_nonet_values(row_number, column_number)): raise ExistentNumberError("Existent number in row, column or nonet", number, row_number, column_number) def __len__(self): return self.n_rows, self.n_columns def __getitem__(self, row_number, column_number): return self.array[column_number][row_number] def __delitem__(self, row_number, column_number): del self.array[column_number][row_number] def __setitem__(self, row_number, column_number, number): self.check(number, row_number, column_number) self.array[column_number][row_number] = number def insert(self, row_number, column_number, number): self.check(row_number, column_number, number) self.array.insert(row_number, column_number, number) def __str__(self): return str(self.array) def get_row_values(self, row_number): # todo implement get_row_values method pass def get_column_values(self, column_number): # todo implement get_column_values method pass def get_nonet_values(self, row_number, column_number): # todo implement get_nonet_values method pass class ExistentNumberError(Exception): def __init__(self, message, number, row_number, column_number): super().__init__(message) self.number = number self.row_number = row_number self.column_number = column_number  Example of use of SudokuArray:  sudoku_array = SudokuArray() sudoku_array[0][0] = 1 # next ExistentNumberError will be raised sudoku_array[0][0] = 1  Of course I could use numpy.array but I think our 9x9 array is very simple for using numpy. Also I want to avoid dependencies. Any idea?

Answer: There are these issues in your attempt:  The if statement in check lacks an opening parenthesis. __len__ should return a number, not a tuple. __getitem__ and similar methods should not take two index arguments, but one. However, this argument can be a tuple (of 2 coordinates) In __setitem__ the call to self.check has arguments in the wrong order. A Sudoku always has the same number of rows and columns, so I would not have separate constructor parameters for the number of rows and the number of columns. Just have one parameter. The insert and __delitem__ methods should not be used on a Sudoku: you don't want to change the number of entries on any row. In the below correction I will still include them, as maybe you have a good reason for this? The get_***_values methods were not implemented.  Here is the suggested code: from collections.abc import MutableSequence from math import isqrt class SudokuArray(MutableSequence): def __init__(self, size=9, init_value=None): self.size = size self.array = [[init_value for _ in range(self.size)] for _ in range(self.size)] def check(self, row_number, column_number, number): if (number in self.get_row_values(row_number) or number in self.get_column_values(column_number) or number in self.get_nonet_values(row_number, column_number)): raise ExistentNumberError("Existent number in row, column or nonet", number, row_number, column_number) def __len__(self): return self.size * self.size def __getitem__(self, coordinates): return self.array[coordinates[0]][coordinates[1]] def __delitem__(self, coordinates): del self.array[coordinates[0]][coordinates[1]] def __setitem__(self, coordinates, number): self.check(coordinates[0], coordinates[1], number) self.array[coordinates[0]][coordinates[1]] = number def insert(self, coordinates, number): self.check(coordinates[0], coordinates[1], number) self.array[coordinates[0]].insert(coordinates[1], number) def __str__(self): return "\n".join(" ".join(map(str, row)) for row in self.array).replace("None", ".") def get_row_values(self, row_number): return self.array[row_number][:] def get_column_values(self, column_number): return [row[column_number] for row in self.array] def get_nonet_values(self, row_number, column_number): width = isqrt(self.size) row_number -= row_number % width column_number -= column_number % width return [val for row in self.array[row_number:row_number+width] for val in row[column_number:column_number+width]]  Example use: sudoku = SudokuArray() sudoku[1, 2] = 9 sudoku[2, 3] = 8 sudoku[5, 5] = 4 sudoku[4, 4] = 3 sudoku[3, 3] = 6 print(sudoku)