How to create a python array

Asked

Viewed 68,693 times

7

I want to create an array where the user specifies the number of rows and the number of columns. Initially an empty matrix was given: matrix = [] The codes must start from there the code below was my attempt:

def gerar_matriz (n_linhas, n_colunas):
        ''' 
          (int,int) -> matrix
        '''
        matriz = []
        matriz.append(" ")
        matriz.append([" "]*num_linhas)

        i = 0
        while i < len(matriz):
            matriz[i].append(" ")
            i += 1


        return matriz

There is a main function that will call this function, but for now my question is just to assemble this matrix.

  • 1

    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.

  • Take a look at this link.

3 answers

9

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.

4

If the intention is only to create a matrix as follows:

[" ", " ", " ", ..., " "]
[" ", " ", " ", ..., " "]
[" ", " ", " ", ..., " "]
[ ...      ...       ...]
[" ", " ", " ", ..., " "]

Just you do:

return [[" "]*n_colunas for _ in range(n_linhas)]

In this way:

def gerar_matriz (n_linhas, n_colunas):
    return [[" "]*n_colunas for _ in range(n_linhas)]

Example:

>>> print(gerar_matriz(2, 3))
[[' ', ' ', ' '], [' ', ' ', ' ']]

The code is the equivalent of:

def gerar_matriz (n_linhas, n_colunas):
    matriz = []

    for _ in range(n_linhas):
        matriz.append( [" "] * n_colunas )

    return matriz

See working on Ideone

2

I did it using random values, but instead random in the variable n you can use input() to define them.

import random
def matriz(n_linhas, n_colunas):
    matriz = [] # Matriz
    linha = [] # Linha

    while len(matriz) != n_linhas: # Quando o número de elementos da matriz(linhas) forem diferentes da quantidade máxima definida pelo usuário, ele ficará rodando.
        n = random.randint(0,99) # Utilizei random para adicionar os valores
        linha.append(n) # Adiciono n à linha

        if len(linha) == n_colunas: # Se a quantidade de elementos for igual à quantidade de colunas definida pelo usuário :
            matriz.append(linha) # Adiciono a linha à matriz
            linha = [] # E zero a "linha" para adicionar outra à matriz
    return matriz # Retorno a mesma


print(matriz(5,4))

An example of output:

>>> [[21, 4, 94, 23], [72, 56, 98, 76], [32, 39, 97, 71], [60, 6, 65, 20], [88, 56, 81, 29]]

Browser other questions tagged

You are not signed in. Login or sign up in order to post.