This is a way to create two-dimensional (2D) lists in Python. We can access elements on each list with an index.
With nested lists, we can create a lookup table or rectangular grid. Jagged row lengths, where each row has a different number of elements, are also allowed.
General idea. We create an empty list and add empty lists to it with append(). We can construct any rectangular (or jagged) list this way. In this example we built a 2 by 2 list.
Append: We first create an empty list with the empty square brackets. Then we call the append method and add two empty lists.
Then: We access each sub-list and call append on it. This appends to the inner lists.
Indexes: We display the element at indexes 0, 0 and this value is 1. With the print() method we can display the entire list contents.
For: This loop can iterate rows and columns in the 2D list. Nested for-loops loop over rows and columns.
Based on: Python 3 Python program that uses 2D list # Create a list. elements =  # Append empty lists in first two indexes. elements.append() elements.append() # Add elements to empty lists. elements.append(1) elements.append(2) elements.append(3) elements.append(4) # Display top-left element. print(elements) # Display entire list. print(elements) # Loop over rows. for row in elements: # Loop over columns. for column in row: print(column, end="") print(end="\n") Output 1 [[1, 2], [3, 4]] 12 34
Jagged lists. The term "jagged" implies that sub lists have uneven lengths. Here we create a list of two lists—one of length 2, the other of length 5. We display their lengths.
Python program that uses jagged lists # A jagged list. values = [[10, 20], [30, 40, 50, 60, 70]] for value in values: # Print each row's length and its elements. print(len(value), value) Output 2 [10, 20] 5 [30, 40, 50, 60, 70]
Nested lists. This is a list of lists, not exactly a 2D list. It does not need to be rectangular—some lists can be longer than others. This can end up saving memory.
Tip: All the methods on list, including "len" and "in," work on nested lists. But they consider only one sub-list at a time.
Caution: For performance, nested lists are not optimal. An array is faster than a list.
Flattened. It is possible to index into a flat array as though it is two-dimensional. We add the first coordinate, "x," and then multiply the second "y" coordinate by the length.
Index: The multiplication of the coordinates returns a single integer for a 2D point.
Here: We define get_element and set_element methods. We compute indexes based on an "x" and "y" coordinate pair.
Python program that uses flattened list def get_element(elements, x, y): # Get element with two coordinates. return elements[x + (y * 10)] def set_element(elements, x, y, value): # Set element with two coordinates. elements[x + (y * 10)] = value # Create a list of 100 elements. elements =  for i in range(0, 100): elements.append(0) i = 0 for x in range(0, 10): for y in range(0, 10): # Set each element in the list to an incremented number. set_element(elements, x, y, i) i += 1 # First in first row. print(get_element(elements, 0, 0)) # Last in first row. print(get_element(elements, 0, 9)) # First in last row. print(get_element(elements, 9, 0)) # Last in last row. print(get_element(elements, 9, 9)) Output 0 9 90 99
Nested versus flat. Suppose it is simple to change a nested list to a flattened, 1D list. This will likely result in a performance increase.
Here: We create a list with two 3-element nested lists. We then create an equivalent 6-element flat list.
Result: Accessing the element at position coordinates 1, 2 is slightly faster in the flattened list.
Note: This approach is more complex at first, but with practice I have found it becomes easy to use and understand.
Python program that times nested, flattened list import time # Nested, 3x2. nested_list =  nested_list.append([10, 20, 30]) nested_list.append([40, 50, 60]) # Flattened, 3x2. flat_list = [10, 20, 30, 40, 50, 60] # Test the two lists. print(nested_list) print(flat_list[1 + (2 * 2)]) print(time.time()) # Version 1: access element in nested list. for i in range(0, 100000000): if nested_list != 60: print(False) print(time.time()) # Version 2: access element in flattened list. for i in range(0, 100000000): if flat_list[1 + (2 * 2)] != 60: print(False) print(time.time()) Output 60 60 1420077374.795 1420077375.334: Nested list, 0.539 s 1420077375.794: Flat list, 0.460 s [PyPy]
Usage. Sometimes a 2D list is helpful in programs. For a simple or small coordinate system or grid, nested lists can be useful. They are flexible. The syntax is clear.
Larger data sizes. For larger or more complex requirements, this approach is not ideal. Another data structure, like an array, is a better choice at this scale.