Pitfalls to avoid when creating 2d lists in Python.
For on 1d lists, see this blog post.
Find source code on GitHub.
A 2d-list in Python can be conceptualized as (row, column) pairs:
(0, 0) (0, 1) (0, 2) (1, 0) (1, 1) (1, 2) (2, 0) (2, 1) (2, 2)
Note that row and column are the opposite of traditional x-y coordinate systems!
Rows count along the
-y axis and are listed first.
Columns count along the
+x axis and are listed second.
(Alternatively, you can do a coordinate rotation in your head:
+x is down,
+y is right).
Python will represent a 2d-list as a list of lists:
[[list], [list], ...]
Each list element is itself a list. For example,
[ # <-- Outer list [00, 01, 02], # <-- Inner list [10, 11, 12], [20, 21, 22], ]
for Loop with Multiplication
This Python FAQ
recommends creating an
M x N list in two steps:
- create a list of
- fill each row with
Ncolumns (in a list)
the_list = [None] * nrows for i in range(nrows): the_list[i] = [value] * ncols
Nested List Comprehension
A 2d list can be created with list comprehensions:
[[value for _ in range(ncols)] for _ in range(nrows)]
In detail, create a list of columns using:
# List of columns [value for _ in range(ncols)]
We can create rows from these columns using this form:
# List of rows, column unspecified [column for _ in range(nrows)]
Substituting for the column gives the original comprehension.
List Comprehension with Multiplication
Multiplication can be used for the inner list comprehension (list of columns):
[[value] * ncols for _ in range(nrows)]
Do not use multiplication for the outer comprehension (list of rows)! See Common Mistakes for details.
The following will give unexpected results!
# Do not do this! [[value] * ncols] * nrows
* operator creates a reference to the original object, not a new object.
This means that:
- The basic type (say,
None) is referenced multiple times (fine)
- A single copy of the list
[None, None, ...]is referenced multiple times (bad!)
[None] * ncols
creates a list of references to the
[None, None, ...]
The problem arises when this is used to populate the rows of a 2d list. This expression:
[None, None, ...] * nrows
creates a list of references to the same list:
[[None, None, ...], [None, None, ...], ...]
Changing a single value makes this apparent:
the_list = [[None] * 2] * 3 # [[None, None], [None, None], [None, None]] the_list = 42 # [[42, None], [42, None], [42, None]]
Numpy offers an N-dimensional array.