Python does not have, despite having several native types, a "matrix" type neither native, nor in its standard library.
numpy
For any serious work involving matrices (that is, you have a problem involving "real-world" matrices) the ideal is to install a separate module that has not only the matrices, but high-performance code for operations in the elements and between the matrices. The most famous for this is by far the numpy. It is automatically installed in Python scientific distributions such as Anaconda and others.
With numpy installed, you have a number of tools to create matrices - one of the most practical is the np.zeros
to which you pass only the desired sizes in each dimension and data types:
In [2]: np.zeros((4,4), dtype=np.float64)
Out[2]:
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
And a cool thing about these matrices is that they’re objects that make use of the methods that use indices on an object (that is, the class methods that are called when we use brackets after the object) - and use tuples in the indices to address the elements - so a[0,0]
will address the element in row zero, column zero of the matrix "a". What’s more, it supports the use of Python’s "Slices" in these indices as well, so you can do this:
In [3]: a = np.zeros((5,5), dtype=np.float64)
In [4]: a[1:4, 1:4] = 1
In [5]: a
Out[5]:
array([[ 0., 0., 0., 0., 0.],
[ 0., 1., 1., 1., 0.],
[ 0., 1., 1., 1., 0.],
[ 0., 1., 1., 1., 0.],
[ 0., 0., 0., 0., 0.]])
And these matrices already work very well with a whole series of operations defined for matrices in mathematics - not just "arrays" of dumb objects - you can add them to each other, or do any other operation. In fact, the numpy project and its matrix handling is so important to Python that during the development of version 3.5 they requested that a new operator be added to the language - the @
which is used for multi-application of matrices. (It is not used in normal Python - any object can implement the method __matmul__
and do something with the operator @
- but it was created at the request of numpy’s staff.
In [6]: a = np.array([[1,2,3], [4,5,6], [7,8,9]], dtype=np.float)
In [7]: a
Out[7]:
array([[ 1., 2., 3.],
[ 4., 5., 6.],
[ 7., 8., 9.]])
In [8]: b = np.array([2,2,2])
In [10]: a@b
Out[10]: array([ 12., 30., 48.])
Now sometimes for very short projects, or for educational purposes, you may want to create your own "multidimensional arrays" - and then you can create lists where each element is a list - with some care -
or - a little better, implement your own class that treats the contents in a similar way to numpy - or even use a dictionary directly.
updating: I just discovered the project tinynumpy: it has the same facilities as numpy arrays for simple things, but its installation is much smaller and it is in pure Python: it may be worth it in environments with restrictions on installing binary files or with limitation of disk space.
lists of lists
Just use standard Python code to create multiple lists within an initial list, and address each element with brackets followed:
In [17]: m = []
In [18]: for y in range(4):
...: linha = []
...: for x in range(4):
...: linha.append(0)
...: m.append(linha)
...:
In [19]: m
Out[19]: [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
In [20]: m[0][0] = 5
In [21]: m
Out[21]: [[5, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Or in a single line:
In [22]: n = [[0] * 4 for i in range(4)]
In [23]: n
Out[23]: [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
And taking some care - for example, if I multiply a same "list" object in trying to get several lines from the matrix, I will actually have copies of the same starting line on all lines, and many bugs:
In [25]: o = [[0] * 4] * 4
In [26]: o
Out[26]: [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
In [27]: o[0][0] = 1
In [28]: o
Out[28]: [[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]
This is the most "simple" way of creating a matrix in Python, as it is in the other answers, but the one that will give more work: the matrices of this type do not enjoy anything of the capabilities of object orientation - every smallest desired operation has to be done by addressing each element of the matrix with external code that uses the two sets of square brackets.
Dict
You can use simple Python dictionaries as matrices. Since tuples can be used inside brackets and can be dictionary keys, you only need a "defaultdict" that returns the initial value for each element that has not yet been used - and, with a minimum of sophistication, checks the matrix boundaries.
Normal dictionaries have the method .setdefault
which can be used in place of the brackets to provide the initial value. It’s cool because you don’t need to build a special object - but it’s bad because it won’t work with the syntax of brackets for reading:
In [29]: m = dict()
In [30]: m.setdefault((0,0), 0)
Out[30]: 0
In [31]: m[0,0] = 1
In [32]: m.setdefault((0,0), 0)
Out[32]: 1
In [33]: m.setdefault((4,4), 0)
Out[33]: 0
custom Dict
Now, the dictionary class project predicts that subclasses may have the method __missing__
that would be called to automatically for a non-existent index.
class M(dict):
def __init__(self, dimensions, default=0):
self.dimensions = dimensions
self.default = default
def _convert(self, index):
if not hasattr(self, '__len__'):
raise IndexError('Use a sequence as index for matrices')
if len(index) != len(self.dimensions):
raise IndexError("Incorrect index dimentsions")
for d, i in zip(self.dimensions, index):
if i < 0 or i >= d:
raise IndexError("Index out of range")
return tuple(index)
def __missing__(self, index):
index = self._convert(index)
return self.get(tuple(index), self.default)
def __setitem__(self, index, value):
index = self._convert(index)
return super().__setitem__(index, value)
def __repr__(self):
if len(self.dimensions) == 2:
result = "[{}]".format("\n".join(", ".join(str(self[i, j]) for j in range(self.dimensions[1])) for i in range(self.dimensions[0])))
else:
result = "<matrix {} >".format(super().__repr__())
return result
custom class
Or, finally, create your own class that implements the methods __getitem__
, __setitem__
and __delitem__
to have a kind of matrix completely under your control - I usually create a class of these to keep representations in memory of what is on the simple game screen in the style of Nake, tetris, "candycrush saga", for example.
Okay, have you [Dit] the question and add what you tried to do? To properly format the code just copy it in the question editor, select it and press the shortcut
Ctrl+K
. Since you are a recent member of the community, I recommend you take the [tour] to understand the basics of how the site works.– Woss
Take a look at this link.
– Solkarped