I simply want to create an empty 10*3*2 array with Python.
I first thought of these one, but this is not working:
parameters = [ [ [] * 2 ]*3 ] * 10
this gives me a vector of ten vectors, with three [] elements in it:
[[[], [], []], [[], [], []], [[], [], []], [[], [], []], [[], [], []],
[[], [], []], [[], [], []], [[], [], []], [[], [], []], [[], [], []]]
that is , if I want to access parameters[0][0][1] I am out of bounds, whereas I want a dimension 2 for the innermost vectors along the third dimension.
then I thought of this
[ [ [[] * 2] ]*3 ] * 10
I was thinking that [[] * 2]
would now bring me the thing I want, an innermost two elements vector. I obtain
[[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]],
[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]],
[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]]]
So, how to do it, or how to escape this initialization?
Kd rgds.
I would recommend you use Numpy for this kind of stuff. It makes accessing columns or rows much easier. For your use case you'd do
import numpy as np
matrix = np.zeros((2,3,10))
second_col = matrix[:,1,:]
Numpy will also take better care of your data, and it implements a lot of the matrix algebra in Fortran or C so it's going to be a lot faster in the (possible) future when you're doing matrix multiplication and the likes.
First of all, you should insert something into the innermost list (like None). Secondly, when you use the multiplication in the outermost list it replicates references to the inner list, so when you change one element, you will also change this element in all the other lists:
>> parameters = [ [ [None] * 2 ]*3 ] * 10
>> print parameters
[[[None, None], [None, None], [None, None]],
[[None, None], [None, None], [None, None]],
[[None, None], [None, None], [None, None]],
[[None, None], [None, None], [None, None]],
[[None, None], [None, None], [None, None]],
[[None, None], [None, None], [None, None]],
[[None, None], [None, None], [None, None]],
[[None, None], [None, None], [None, None]],
[[None, None], [None, None], [None, None]],
[[None, None], [None, None], [None, None]]]
>> parameters[0][0][1]=1
>> print parameters
[[[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]]]
Therefore, you should rather use list comprehensions:
>> parameters=[[[None for i in range(2)] for j in range(3)] for k in range(10)]
However, I would recommend to use numpy
as suggested in one of the other answers.
Here's one of the problems with what you're doing.
Let's say you're creating an array, like so:
>>> l = [ [ [[] * 2] ]*3 ] * 10
>>> l
[[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]]]
Seems okay so far. Let's set something in the array.
>>> l[0][0][0] = 2
>>> l
[[[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]]]
Woah! We set 1 item in it, but it changed everything! How'd that happen?
Well, it appears that we have 60 list objects. However, we actually have 60 references to one list object. Change one, change them all.
TL;DR: Don't use the multiply operator on a list of lists.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With