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?
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))
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)
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-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]]]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.