A Python 2D list is a list containing other lists as its elements. The inner lists can represent rows, while the values inside each row can represent columns.
For example, a 2D list can store data in a table-like or matrix-like structure. Python lists do not require every row to have the same length, although matrix-style data usually uses rows of equal length.
For large numerical matrix operations, libraries such as NumPy are usually more suitable. A Pandas DataFrame is useful when working with labeled tabular data. However, standard Python lists are useful for learning and for many smaller tasks.
We can create a 2D list by placing several lists inside another list.
my_list=[
[1, 0, 0, 4, 6],
[3, 9, 8, 0, 0],
[3, 9, 1, 1, 5],
[0, 9, 3, 0, 8],
[8, 6, 1, 9, 7]
]
This example contains five rows. Each row contains five elements.
A for loop can read and display each inner list as one row.
my_list=[
[1, 0, 0, 4, 6],
[3, 9, 8, 0, 0],
[3, 9, 1, 1, 5],
[0, 9, 3, 0, 8],
[8, 6, 1, 9, 7]
]
for row in my_list:
print(row)
Output
[1, 0, 0, 4, 6]
[3, 9, 8, 0, 0]
[3, 9, 1, 1, 5]
[0, 9, 3, 0, 8]
[8, 6, 1, 9, 7]
Two indexes are used to access an individual element. The first index selects the row, and the second index selects the element inside that row.
print(my_list[3][4])
Output
8
Here, my_list[3] selects the fourth row because indexing starts from 0. The second index, [4], selects the fifth element of that row.
A single index returns one complete row.
print(my_list[2])
Output
[3, 9, 1, 1, 5]
Index 2 selects the third row.
To collect one column, we can read the same index from every row.
The following example reads index 3, which represents the fourth column.
column=[]
for row in my_list:
column.append(row[3])
print(column)
Output
[4, 0, 1, 0, 9]
The same result can be created using list comprehension.
column=[row[3] for row in my_list]
print(column)
Output
[4, 0, 1, 0, 9]
Nested loops can access every individual element of a 2D list.
my_list=[
['abc', 'def', 'ghi', 'jkl'],
['mno', 'pkr', 'frt', 'qwr'],
['asd', 'air', 'abc', 'zpq'],
['zae', 'vbg', 'qir', 'zab']
]
for row in my_list:
for item in row:
print(item, end=' ')
print()
Output
abc def ghi jkl
mno pkr frt qwr
asd air abc zpq
zae vbg qir zab
The outer loop reads one row at a time. The inner loop reads each element from that row.
Python lists are mutable, so an existing value inside a 2D list can be changed using its row and column indexes.
my_list=[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
my_list[1][2]=50
print(my_list)
Output
[[1, 2, 3], [4, 5, 50], [7, 8, 9]]
The value at the second row and third column is changed from 6 to 50.
A new row can be added using the
append() method.
my_list=[
[1, 2, 3],
[4, 5, 6]
]
my_list.append([7, 8, 9])
print(my_list)
Output
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
The complete list [7, 8, 9] becomes a new row.
To add a new column, add one value to each existing row.
my_list=[
[1, 2],
[3, 4],
[5, 6]
]
for row in my_list:
row.append(0)
print(my_list)
Output
[[1, 2, 0], [3, 4, 0], [5, 6, 0]]
Each call to append(0) adds one new element to the end of a row, creating a new column.
The pop() method can remove a row by its index.
my_list=[
[1, 0, 0, 4, 6],
[3, 9, 8, 0, 0],
[3, 9, 1, 1, 5],
[0, 9, 3, 0, 8],
[8, 6, 1, 9, 7]
]
my_list.pop(2)
print(my_list)
Output
[[1, 0, 0, 4, 6], [3, 9, 8, 0, 0], [0, 9, 3, 0, 8], [8, 6, 1, 9, 7]]
Index 2 represents the third row because list indexes start from 0.
To delete a complete column, remove the element at the same index from every row.
The following example removes index 3, which represents the fourth column.
my_list=[
[1, 0, 0, 4, 6],
[3, 9, 8, 0, 0],
[3, 9, 1, 1, 5],
[0, 9, 3, 0, 8],
[8, 6, 1, 9, 7]
]
for row in my_list:
row.pop(3)
print(my_list)
Output
[[1, 0, 0, 6], [3, 9, 8, 0], [3, 9, 1, 5], [0, 9, 3, 8], [8, 6, 1, 7]]
A regular loop is clearer here because pop() is being used to modify each row.
When creating a 2D list with repeated values, avoid multiplying a list containing another mutable list.
For example:
my_list=[[0] * 3] * 3
my_list[0][0]=9
print(my_list)
Output
[[9, 0, 0], [9, 0, 0], [9, 0, 0]]
All three positions changed because the outer list contains references to the same inner list.
Create each row separately using list comprehension instead.
my_list=[[0] * 3 for _ in range(3)]
my_list[0][0]=9
print(my_list)
Output
[[9, 0, 0], [0, 0, 0], [0, 0, 0]]
Now each row is an independent list.
We can create a square 2D list using
random numbers. In this example, n controls the number of rows and columns.
from random import randrange
n=5
my_list=[]
for i in range(n):
row=[]
for j in range(n):
row.append(randrange(10))
my_list.append(row)
for row in my_list:
print(row)
Sample Output
[5, 1, 7, 6, 6]
[9, 0, 1, 1, 2]
[9, 2, 2, 7, 4]
[6, 2, 6, 9, 6]
[7, 1, 6, 4, 5]
The output changes each time the program runs because randrange(10) generates values from 0 through 9.
The same 2D list can also be created using nested list comprehension.
from random import randrange
n=5
my_list=[
[randrange(10) for j in range(n)]
for i in range(n)
]
for row in my_list:
print(row)
The transpose changes rows into columns and columns into rows.
We can use zip() with the unpacking operator * to transpose a rectangular 2D list.
my_list=[
[1, 2],
[3, 4],
[5, 6]
]
transposed=[
list(row)
for row in zip(*my_list)
]
print(transposed)
Output
[[1, 3, 5], [2, 4, 6]]
The first column becomes the first row, and the second column becomes the second row.
For a square 2D list, the main diagonal contains elements where the row index and column index are the same.
my_list=[
[1, 0, 0, 4, 6],
[3, 9, 8, 0, 0],
[3, 9, 1, 1, 5],
[0, 9, 3, 0, 8],
[8, 6, 1, 9, 7]
]
n=len(my_list)
main_diagonal=sum(
my_list[i][i]
for i in range(n)
)
print(main_diagonal)
Output
18
The main diagonal values are 1, 9, 1, 0, and 7.
Their sum is:
1 + 9 + 1 + 0 + 7 = 18
The secondary diagonal runs from the top-right corner to the bottom-left corner.
secondary_diagonal=sum(
my_list[i][n-1-i]
for i in range(n)
)
print(secondary_diagonal)
Output
24
The secondary diagonal values are 6, 0, 1, 9, and 8.
Their sum is:
6 + 0 + 1 + 9 + 8 = 24
Read more about the sum() function.
my_list[row][column].append() to add rows or new elements to each row.pop() to remove rows or column elements.[[0] * n] * n when independent rows are required.zip(*my_list) can transpose a rectangular 2D list.sum() function can calculate diagonal totals of a square matrix-like list.Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.