1

There have been a couple questions on SO about how to initialize a 2-dimensional matrix, with the answer being something like this:

matrix = [[0 for x in range(10)] for x in range(10)]

Is there any way to generalize this to n dimensions without using for blocks or writing out a really long nested list comprehension?

  • 2
    Whenever you are working with matrixes, you should consider using [NumPy](http://www.numpy.org/). It is very efficient and was designed for this purpose. –  Oct 23 '14 at 16:46
  • possible duplicate of [How do I get a empty array of any size I want in python?](http://stackoverflow.com/questions/5205575/how-do-i-get-a-empty-array-of-any-size-i-want-in-python) – Lukas Graf Oct 23 '14 at 16:48
  • I think this could be the canonical question on initializing a matrix, but otherwise it might be a duplicate. – Russia Must Remove Putin Oct 23 '14 at 19:08

4 Answers4

0

As integers are immutable you can reduce your code to:

matrix = [[0] * 10 for x in range(10)]

As @iCodez mentioned in comments if NumPy is an option you can simply do:

import numpy as np                                              
matrix = np.zeros((10, 10)) 
Community
  • 1
  • 1
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
0

If you really want a matrix, np.zeros and np.ones can quickly create such a 2 dimensional array for instantiating a matrix:

import numpy as np
my_matrix = np.matrix(np.zeros((10,10)))

To generalize to n dimensions, you can't use a matrix, which by definition is 2 dimensional:

n_dimensions = 3
width = 10

n_dimensional_array = np.ones((width,) * n_dimensions)
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
-1

I agree that if numpy is an option, it's a much easier way to work with matrices. I highly recommend it.

That being said, this recursive function is a reasonable way to generalize your code to n dimensions. The first parameter is a list or tuple specifying how large each dimension should be (and, indirectly, how many dimensions). The second parameter is the constant value to fill the matrix with (in your example, 0):

def init(sizes, value=0):
    if (len(sizes) == 1):
        return [value] * sizes[0]
    else:

        # old code - fixed per comment. This method does not create
        # sizes[0] *new* lists, it just repeats the same list
        # sizes[0] times. This causes unexpected behavior when you
        # try to set an item in a list and all of its siblings get
        # the same change
        # return [init(sizes[1:], value)] * sizes[0]

        # this method works better; it creates a new list each time through
        return [init(sizes[1:], value) for i in xrange(sizes[0])]

matrix = init((2,3,4), 5)
matrix[0][0][0] = 100 # setting value per request in comment
print matrix
>>> [[[100, 5, 5, 5], [5, 5, 5, 5], [5, 5, 5, 5]], [[5, 5, 5, 5], [5, 5, 5, 5], [5, 5, 5, 5]]]

N-dimensional arrays are a little hard to print on a 2D screen, but you can see the structure of matrix a little more easily in the snippet below which I manually indented. It's an array of length 2, containing arrays of length 3, containing arrays of length 4, where every value is set to 5:

[
    [
        [100, 5, 5, 5],
        [5, 5, 5, 5],
        [5, 5, 5, 5]
    ],
    [
        [5, 5, 5, 5],
        [5, 5, 5, 5],
        [5, 5, 5, 5]
    ]
]
Brian Putnam
  • 599
  • 1
  • 5
  • 12
  • How about doing `matrix[0][0] = 100` and then printing `matrix` after it? – Ashwini Chaudhary Oct 23 '14 at 17:57
  • @AshwiniChaudhary good catch, thanks. I changed your snippet to `matrix[0][0][0] = 100` since this is a 3D array (I assume that's what you meant?). Does the edited code pass muster now? – Brian Putnam Oct 23 '14 at 19:12
-1

@brian-putman was faster and better... anyway, this is my solution:

init = lambda x, y: [init(x, y-1) if y>1 else 0 for _ in xrange(x)]

that generates only square matrices of size x filled with zeroes in y dimensions. called like this

init(5, 3)

[[[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]],
 [[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]],
 [[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]],
 [[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]],
 [[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]]]
fransua
  • 1,559
  • 13
  • 30