Reputation: 2941
There is no array type in python, but to emulate it we can use lists. I want to have 2d array-like structure filled in with zeros. My question is: what is the difference, if any, in this two expressions:
zeros = [[0 for i in xrange(M)] for j in xrange(M)]
and
zeros = [[0]*M]*N
Will zeros
be same? which one is better to use by means of speed and readability?
Upvotes: 68
Views: 149955
Reputation: 1
time = np.arange(0,12,2)
N = [np.zeros_like(time) for _ in range(2)]
print(N)
Result:
[array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])]
N[0][1] = 2
print(N)
Result:
[array([0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])]
If we want the length of the array N to be same as of another array S, say, then:
N = [np.zeros_like(time) for _ in range(len(S))]
In this way we can have two arrays S and N where each element in S will have a corresponding array-element in N. For ex., S=[1-30:days in a month] and N=[hourly temperature for each day: 30 such arrays]. This N can be initialized just like above.
Upvotes: -3
Reputation: 309831
You should use numpy.zeros
. If that isn't an option, you want the first version. In the second version, if you change one value, it will be changed elsewhere in the list -- e.g.:
>>> a = [[0]*3]*3
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0] = 1
>>> a
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]
This is because (as you read the expression from the inside out), you create a list of 10 zeros. You then create a list of 10 references to that initial list of 10 zeros.
Note that this will also work and it avoids the nested list comprehension:
zeros = [ [0]*M for _ in range(N) ]
If numpy
isn't on the table, this is the form I would use.
(Use xrange
if you're still stuck in the python2.x dark ages :).)
Upvotes: 112
Reputation: 1032
Zhe Hu's answer is the safer one and should have been the best answer. This is because if we use the accepted answer method
a = [[0] * 2] * 2
a[0][0] = 1
print(a)
will give the answer
[[1,0],[1,0]]
So even though you just want to update the first row first column value, all the values in the same column get updated. However
a = [[0] * 2 for _ in range(2)]
a[0][0] = 1
print(a)
gives the correct answer
[[1,0],[0,0]]
Upvotes: 5
Reputation: 8285
In second case you create a list of references to the same list. If you have code like:
[lst] * N
where the lst
is a reference to a list, you will have the following list:
[lst, lst, lst, lst, ..., lst]
But because the result list contains references to the same object, if you change a value in one row it will be changed in all other rows.
Upvotes: 25
Reputation: 4007
for Python 3 (no more xrange), the preferred answer
zeros = [ [0] * N for _ in range(M)]
for M x N array of zeros
Upvotes: 53