Initialise matrix in python [duplicate]
Possible Duplicate:
Python list problem
I try to initialise a matrix in python. First I did this:
>>> M=[[0]*4]*4
But here is my probleme, every line is changing when I change the first one:
>>> M
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> M[1][1]=1
>>> M
[[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]]
So I did it this way:
>>> M= [ [ 0 for i in range(4) ] for j in range(4) ]
And ut works fine:
>>> M
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> M[1][1]=1
>>> M
[[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
My question is:
What these two expressions really mean ? ans why the first one is behaving this way ?
Thanks in advance for you help.
When you multiply those lists, Python is copying them by reference rather than creating entirely new objects.
A simple example might help, showing what happens with copy by reference:
>>> pie = ['apple', 'cherry', 'pecan']
>>> pie_copy = pie
>>> pie_copy[0] = 'banana'
>>> pie
['banana', 'cherry', 'pecan']
>>> pie is pie_copy
True
>>> new_pie = ['banana', 'cherry', 'pecan']
>>> pie is new_pie
False
In the same way that pie_copy and pie point to the same list, when building lists by multiplying, all the copies point to the same list.
In your second snippet using range()
and list comprehensions, you aren't taking a single list and copying it several times; each iteration in the comprehension is creating a new list, so you don't suffer from the same copy by reference problem.
Because here M=[[0]*4]*4
You create a links on objects.
It's the similar as
>>> a = [0, 0, 0]
>>> b = [a,a,a]
>>> b
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[1] = 1
>>> b
[[0, 1, 0], [0, 1, 0], [0, 1, 0]]
>>>
UPD links I meant references, sorry if little confusing
Say a
is some python object. Then [a] * 4
is equivalent to [a, a, a, a]. What this means depends on whether a
is mutable or not. Numbers, strings and tuples are not, so if a
is one of these kinds of objects (0
in your example), then you get 4 independently changeable copies. Lists, dictionaries and sets are mutable, and in this case you just get 4 references to the same object, in your case the list [0] * 4
. Exploiting this knowledge, you'll see that you can do this:
M = [[0] * 4 for i in range(4)]
and get what you want.
精彩评论