Nest lists in lists you don't need to predefine the length of a list to use it and you can append on to it. Want another dimension simply append another list to the inner most list.
[[[a1, a2, a3] , [b1, b2, b3] , [c1, c2, c3]],
[[d1, d2, d3] , [e1, e2, e3] , [f1, f2, f3]]]
and to use them easily just look at Nested List Comprehensions
Answer from VoronoiPotato on Stack OverflowNest lists in lists you don't need to predefine the length of a list to use it and you can append on to it. Want another dimension simply append another list to the inner most list.
[[[a1, a2, a3] , [b1, b2, b3] , [c1, c2, c3]],
[[d1, d2, d3] , [e1, e2, e3] , [f1, f2, f3]]]
and to use them easily just look at Nested List Comprehensions
In python there is no need to declare list size on forehand.
an example of reading lines to a file could be this:
file_name = "/path/to/file"
list = []
with open(file_name) as file:
file.readline
if criteria:
list.append(line)
For multidimensional lists. create the inner lists in a function on and return it to the append line. like so:
def returns_list(line):
multi_dim_list = []
#do stuff
return multi_dim_list
exchange the last row in the first code with
list.append(returns_list(line))
Videos
Defining a 2D array like this: x = 2 * [[]] puts the same list in both places in the container list as is happening in your case.
Try defining the array like x = [[],[]]
>>> x = [[],[]]
>>> x[0].append(1)
>>> x
[[1], []]
If you know the sizes,
ar = []
for i in range(5):
ar.append([])
for j in range(2):
ar[i].append(1)
Create the 2D array up front, and fill the rows while looping:
my_array = numpy.empty((len(huge_list_of_lists), row_length))
for i, x in enumerate(huge_list_of_lists):
my_array[i] = create_row(x)
where create_row() returns a list or 1D NumPy array of length row_length.
Depending on what create_row() does, there might be even better approaches that avoid the Python loop altogether.
Just pass the list of lists to numpy.array, keep in mind that numpy arrays are ndarrays, so the concept to a list of lists doesn't translate to arrays of arrays it translates to a 2d array.
>>> import numpy as np
>>> a = [[1., 2., 3.], [4., 5., 6.]]
>>> b = np.array(a)
>>> b
array([[ 1., 2., 3.],
[ 4., 5., 6.]])
>>> b.shape
(2, 3)
Also ndarrays have nd-indexing so [1][1] becomes [1, 1] in numpy:
>>> a[1][1]
5.0
>>> b[1, 1]
5.0
Did I misunderstand your question?
You defiantly don't want to use numpy.append for something like this. Keep in mind that numpy.append has O(n) run time so if you call it n times, once for each row of your array, you end up with a O(n^2) algorithm. If you need to create the array before you know what all the content is going to be, but you know the final size, it's best to create an array using numpy.zeros(shape, dtype) and fill it in later. Similar to Sven's answer.
Here is how I would go about doing it
array2d = [list() for f in xrange(n)]
This creates N empty lists. From here you can index them like
array2d[x][y]
An Example in use
array2d = [list() for f in xrange(3)] # We have Three Empty Rows
# Array looks like this -- [[] [] []]
#lets add an item into the first row
array2d[0].append("A")
#Now it looks like this -- [["A"] [] []]
This should solve your problem. The function grow_rows will add any needed rows, using a fixed column count and initializing the entries with 0 (which you can change to anything you like):
def grow_rows(arr, row_cnt, col_cnt):
missing = row_cnt - len(arr)
if missing > 0:
arr.extend([[0] * col_cnt for i in range(missing)])
Here's an example using a fixed column count of 3. Before accessing an element in a row that has not yet been allocated, it calls grow_rows to create the needed rows:
col_cnt = 3
arr = []
print(arr)
grow_rows(arr, 2, col_cnt)
print(arr)
arr[1][2] = 123
print(arr)
Here is the output:
[]
[[0, 0, 0], [0, 0, 0]]
[[0, 0, 0], [0, 0, 123]]
Do you mean something like the following?
class DynamicList(list):
def __getslice__(self, i, j):
return self.__getitem__(slice(i, j))
def __setslice__(self, i, j, seq):
return self.__setitem__(slice(i, j), seq)
def __delslice__(self, i, j):
return self.__delitem__(slice(i, j))
def _resize(self, index):
n = len(self)
if isinstance(index, slice):
m = max(abs(index.start), abs(index.stop))
else:
m = index + 1
if m > n:
self.extend([self.__class__() for i in range(m - n)])
def __getitem__(self, index):
self._resize(index)
return list.__getitem__(self, index)
def __setitem__(self, index, item):
self._resize(index)
if isinstance(item, list):
item = self.__class__(item)
list.__setitem__(self, index, item)
>>> mat = DynamicList()
>>> mat[0] = ['row1','row1','row1']
>>> mat[1] = ['row2','row2']
>>> mat[2]= ['row3']
>>> mat
[['row1', 'row1', 'row1'], ['row2', 'row2'], ['row3']]
>>> print mat[1][1]
row2
>>> mat[5][5] = 'row5'
>>> mat
[['row1', 'row1', 'row1'], ['row2', 'row2'], ['row3'], [], [], [[], [], [], [],
[], 'row5']]
>>> print mat[5]
[[], [], [], [], [], 'row5']
>>> print mat[5][5]
row5
How about using NumPy's matrix class?
I have a class where it should create a 2D list depending on the given size x and y. However, noticed that the following does not work.
self.grid = [[0] * self.sizeY] * self.sizeX
self.grid[1][0] = "TEST"
The output:
[['TEST', 0, 0, 0, 0], ['TEST', 0, 0, 0, 0], ['TEST', 0, 0, 0, 0], ['TEST', 0, 0, 0, 0], ['TEST', 0, 0, 0, 0]]
While the following works fine as expected:
self.grid = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
self.grid[1][0] = "TEST"
The output:
[[0, 0, 0, 0, 0], ['TEST', 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
As you can see in the first example when the result is not what is expected, location [1][0] is being stored 5 times as if all 'rows' are the same.
Any ideas on how to create the 2D list dynamically?
You can just define
Arrays = []
It is enough to hold your dynamic array.
AnotherArray1 = []
AnotherArray2 = []
Arrays.append(AnotherArray1)
Arrays.append(AnotherArray2)
print Arrays
Hope this solves your problem!
Consider using
Arrays = []
and later, when you are assigning your results use
Arrays.append([result])
This is assuming that your result comes in slices, but not as an array. No matter your actual return value layout, a variation of the above .append() should do the trick, as it allows you to dynamically extend your array. If your result comes as an array, it would simply be
Arrays.append(result)
and so on