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))
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]]
How to define a dynamic two-dimensional array in python? - Stack Overflow
python - Create a dynamic 2D numpy array on the fly - Stack Overflow
Two Dimensional List - dynamically creating it does not work, while manually works fine.
Creating a dynamic array in python - Stack Overflow
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)
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?
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.
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're technically trying to index an uninitialized array. You have to first initialize the outer list with lists before adding items; Python calls this "list comprehension".
# Creates a list containing 5 lists, each of 8 items, all set to 0
w, h = 8, 5
Matrix = [[0 for x in range(w)] for y in range(h)]
#You can now add items to the list:
Matrix[0][0] = 1
Matrix[6][0] = 3 # error! range...
Matrix[0][6] = 3 # valid
Note that the matrix is "y" address major, in other words, the "y index" comes before the "x index".
print Matrix[0][0] # prints 1
x, y = 0, 6
print Matrix[x][y] # prints 3; be careful with indexing!
Although you can name them as you wish, I look at it this way to avoid some confusion that could arise with the indexing, if you use "x" for both the inner and outer lists, and want a non-square Matrix.
If you really want a matrix, you might be better off using numpy. Matrix operations in numpy most often use an array type with two dimensions. There are many ways to create a new array; one of the most useful is the zeros function, which takes a shape parameter and returns an array of the given shape, with the values initialized to zero:
>>> import numpy
>>> numpy.zeros((5, 5))
array([[ 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.]])
Here are some other ways to create 2-d arrays and matrices (with output removed for compactness):
numpy.arange(25).reshape((5, 5)) # create a 1-d range and reshape
numpy.array(range(25)).reshape((5, 5)) # pass a Python range and reshape
numpy.array([5] * 25).reshape((5, 5)) # pass a Python list and reshape
numpy.empty((5, 5)) # allocate, but don't initialize
numpy.ones((5, 5)) # initialize with ones
numpy provides a matrix type as well, but it is no longer recommended for any use, and may be removed from numpy in the future.