1

I want to create a nested array of 0s of m x n dimensions. I will be iterating through the array and assigning values later.

If I do this:

l = [[0] * 3] * 3
for i in range(3):
    for j in range(3):
        if i == 0:
            l[i][j] = 1

My conditional doesn't seem to apply and every value is assigned to the list regardless of i. I know the problem is caused by copying the lists of 0s in the first line of code. So I took a slice of each inner list like this to fix it:

l = [[0] * 3] * 3
for i in range(3):
    l[i] = l[i][:]
    for j in range(3):
        if i == 0:
            l[i][j] = 1

This feels redundant and I'm wondering if there's a better way to initialize nested lists.

1
  • Note if you were using numpy this would just be numpy.zeros((m, n)) Commented May 26, 2017 at 7:02

1 Answer 1

0

Your issue is that lists in python are mutable and when copying them using * you actually copying the reference to the same list, and not creating new lists.

>>> l = [[0]*3]*3
>>> l
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> l[0][0] = 1
>>> l
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

You want to make your lists different like that by creating theme separately:

>>> l = [[0 for _ in range(3)] for _ in range(3)]  # each list created by it own, and not as you did when it just a copy to the reference to the same list.
>>> l[0][0] = 1
>>> l
[[1, 0, 0], [0, 0, 0], [0, 0, 0]]
Sign up to request clarification or add additional context in comments.

4 Comments

Lists are mutable in both of your examples; the problem is the reference copying.
I was referring to the opening statement: "Your issue is that lists in python are mutable"; I wouldn't bury the actual issue in a code comment.
Got it, you're right, updated the answer.
Thank you, this is exactly what I needed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.