1

I have the following issue:

I have a list of lists with the following declaration:

As = [[0]*3]*3

I then try to change the values of this "matrix" with this:

for i in range(3):
    for j in range(3):
        As[i][j] = calculate(A, i, j)*((-1)**(i+j))

As you may have guessed, this is used in calculating the inverse of a 3x3 matrix.

The function calculate returns the following values:

4.0     
-2.0    
-3.0    
-4.0    
-10.0   
9.0     
4.0     
10.0    
-21.0   

However, As has the following value:

[[4.0, -10.0, -21.0], [4.0, -10.0, -21.0], [4.0, -10.0, -21.0]], which is unexpected.

What am I missing?

2 Answers 2

2

When you build a list like this [[0]*3]*3 you are creating 3 references to the same list, use a list comprehension instead:

[[0 for _ in xrange(3)] for _ in xrange(3)]

See how in the comprehension here just the [0][0] is modified:

>>> l1 = [[0]*3]*3
>>> l1[0][0] = 10
>>> l1
[[10, 0, 0], [10, 0, 0], [10, 0, 0]]
>>> l2 = [[0 for _ in xrange(3)] for _ in xrange(3)]
>>> l2[0][0] = 10
>>> l2
[[10, 0, 0], [0, 0, 0], [0, 0, 0]]
Sign up to request clarification or add additional context in comments.

2 Comments

There's no need to construct the inner list using a comprehension. In fact, the list will refer to the same int instances anyway, since Python caches integers in [-5, 256]. The result is therefore identical to [0] * 3.
@WillVousden, it was just for clarifiying the concept, It usually clears my mind to use for ranges instead of * operator for this purpouse
1

The problem is in your first line:

As = [[0]*3]*3

This is equivalent to the following:

a = [0] * 3
As = [a] * 3

As therefore contains three references to the same list:

>>> for a in As:
...     print(id(a))
...
4293437996
4293437996
4293437996

So when you change this list, it's reflected in all of the rows of your matrix.

To get around this, you can use a list comprehension to construct the outer list:

As = [[0] * 3 for _ in xrange(3)]

Note that the inner list [0] * 3 is fine, since the list contains only an integer, which is immutable. It therefore doesn't matter that the list refers to the same instance of that integer, since they can't be changed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.