Cómo definir una matriz bidimensional en Python

Quiero definir una matriz bidimensional sin una longitud inicializada como esta:

Matrix = [][] 

Pero no funciona…

He probado el siguiente código, pero también es incorrecto:

 Matrix = [5][5] 

Error:

 Traceback ... IndexError: list index out of range 

Cual es mi error

Técnicamente estás tratando de indexar una matriz sin inicializar. Primero debe inicializar la lista externa con listas antes de agregar elementos; Python llama a esto “lista de comprensión”.

 # 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)] 

Ahora puede agregar elementos a la lista:

 Matrix[0][0] = 1 Matrix[6][0] = 3 # error! range... Matrix[0][6] = 3 # valid print Matrix[0][0] # prints 1 x, y = 0, 6 print Matrix[x][y] # prints 3; be careful with indexing! 

Aunque puede nombrarlos como desee, lo veo de esta manera para evitar alguna confusión que pueda surgir con la indexación, si usa “x” para las listas internas y externas, y desea una Matriz no cuadrada.

Si realmente desea una matriz, puede que sea mejor usar numpy . Las operaciones matriciales en numpy suelen usar un tipo de matriz con dos dimensiones. Hay muchas formas de crear una nueva matriz; una de las más útiles es la función de zeros , que toma un parámetro de forma y devuelve una matriz de la forma dada, con los valores inicializados a cero:

 >>> 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.]]) 

numpy proporciona un tipo de matrix . Es menos usado, y algunas personas recomiendan no usarlo. Pero es útil para las personas que vienen a numpy de Matlab y en otros contextos. ¡Pensé que lo incluiría ya que estamos hablando de matrices!

 >>> numpy.matrix([[1, 2], [3, 4]]) matrix([[1, 2], [3, 4]]) 

Aquí hay algunas otras formas de crear matrices y matrices 2-d (con salida eliminada por compacidad):

 numpy.matrix('1 2; 3 4') # use Matlab-style syntax 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.ndarray((5, 5)) # use the low-level constructor 

Aquí hay una notación más corta para inicializar una lista de listas:

 matrix = [[0]*5 for i in range(5)] 

Desafortunadamente, acortar esto a algo como 5*[5*[0]] realmente no funciona porque terminas con 5 copias de la misma lista, así que cuando modificas una de ellas, todas cambian, por ejemplo:

 >>> matrix = 5*[5*[0]] >>> matrix [[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]] >>> matrix[4][4] = 2 >>> matrix [[0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2]] 

Si desea crear una matriz vacía, la syntax correcta es

 matrix = [[]] 

Y si quieres generar una matriz de tamaño 5 rellena con 0,

 matrix = [[0 for i in xrange(5)] for i in xrange(5)] 

Si todo lo que desea es un contenedor bidimensional para contener algunos elementos, podría usar un diccionario en su lugar:

 Matrix = {} 

Entonces puedes hacer:

 Matrix[1,2] = 15 print Matrix[1,2] 

Esto funciona porque 1,2 es una tupla, y la estás utilizando como una clave para indexar el diccionario. El resultado es similar a una matriz dispersa tonta.

Según lo indicado por osa y Josap Valls, también puede utilizar Matrix = collections.defaultdict(lambda:0) para que los elementos que faltan tengan un valor predeterminado de 0 .

Vatsal señala además que este método probablemente no sea muy eficiente para matrices grandes y solo debe usarse en partes del código que no son críticas para el rendimiento.

En Python estarás creando una lista de listas. No tiene que declarar las dimensiones antes de tiempo, pero puede hacerlo. Por ejemplo:

 matrix = [] matrix.append([]) matrix.append([]) matrix[0].append(2) matrix[1].append(3) 

Ahora matrix [0] [0] == 2 y matrix [1] [0] == 3. También puede usar la syntax de comprensión de lista. Este ejemplo lo usa dos veces para construir una “lista bidimensional”:

 from itertools import count, takewhile matrix = [[i for i in takewhile(lambda j: j < (k+1) * 10, count(k*10))] for k in range(10)] 

La respuesta aceptada es buena y correcta, pero me tomó un tiempo entender que también podría usarla para crear una matriz completamente vacía.

 l = [[] for _ in range(3)] 

resultados en

 [[], [], []] 

Debe hacer una lista de listas, y la mejor manera es usar las comprensiones anidadas:

 >>> matrix = [[0 for i in range(5)] for j in range(5)] >>> pprint.pprint(matrix) [[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]] 

En su ejemplo [5][5] , está creando una lista con un entero “5” en el interior, e intenta acceder a su quinto elemento, y eso naturalmente genera un IndexError porque no hay un quinto elemento:

 >>> l = [5] >>> l[5] Traceback (most recent call last): File "", line 1, in  IndexError: list index out of range 
 rows = int(input()) cols = int(input()) matrix = [] for i in range(rows): row = [] for j in range(cols): row.append(0) matrix.append(row) print(matrix) 

¿Por qué un código tan largo, que también en Python preguntas?

Hace mucho tiempo, cuando no estaba cómodo con Python, vi las respuestas de una sola línea para escribir matrices 2D y me dije a mí mismo que no volvería a usar la matriz 2D en Python. (Esas líneas simples daban bastante miedo y no me dieron ninguna información sobre lo que estaba haciendo Python. También tenga en cuenta que no estoy al tanto de estas taquigrafías).

De todos modos, aquí está el código para un principiante que proviene de C, CPP y Java.

Nota para los amantes y expertos de Python: Por favor, no rechace la votación solo porque escribí un código detallado.

Para declarar una matriz de ceros (unos):

 numpy.zeros((x, y)) 

p.ej

 >>> numpy.zeros((3, 5)) array([[ 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0.]]) 

o numpy.ones ((x, y)) por ejemplo

 >>> np.ones((3, 5)) array([[ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.]]) 

Incluso tres dimensiones son posibles. ( http://www.astro.ufl.edu/~warner/prog/python.html ver -> Matrices multidimensionales)

Una reescritura para facilitar la lectura:

 # 2D array/ matrix # 5 rows, 5 cols rows_count = 5 cols_count = 5 # create # creation looks reverse # create an array of "cols_count" cols, for each of the "rows_count" rows # all elements are initialized to 0 two_d_array = [[0 for j in range(cols_count)] for i in range(rows_count)] # index is from 0 to 4 # for both rows & cols # since 5 rows, 5 cols # use two_d_array[0][0] = 1 print two_d_array[0][0] # prints 1 # 1st row, 1st col (top-left element of matrix) two_d_array[1][0] = 2 print two_d_array[1][0] # prints 2 # 2nd row, 1st col two_d_array[1][4] = 3 print two_d_array[1][4] # prints 3 # 2nd row, last col two_d_array[4][4] = 4 print two_d_array[4][4] # prints 4 # last row, last col (right, bottom element of matrix) 

Estoy en mi primer script de Python, y estaba un poco confundido por el ejemplo de la matriz cuadrada, así que espero que el siguiente ejemplo le ayude a ahorrar algo de tiempo:

  # Creates a 2 x 5 matrix Matrix = [[0 for y in xrange(5)] for x in xrange(2)] 

así que eso

 Matrix[1][4] = 2 # Valid Matrix[4][1] = 3 # IndexError: list index out of range 

Utilizar:

 matrix = [[0]*5 for i in range(5)] 

El * 5 para la primera dimensión funciona porque en este nivel los datos son inmutables.

Usando NumPy puedes inicializar una matriz vacía como esta:

 import numpy as np mm = np.matrix([]) 

Y luego adjuntar datos como este:

 mm = np.append(mm, [[1,2]], axis=1) 

Leí en archivos separados por comas como este:

 data=[] for l in infile: l = split(',') data.append(l) 

La lista “datos” es una lista de listas con datos de índice [fila] [col]

Así es como normalmente creo arrays 2D en Python.

 col = 3 row = 4 array = [[0] * col for _ in range(row)] 

Me parece que esta syntax es fácil de recordar en comparación con el uso de to para bucles en una lista de comprensión.

Utilizar:

 import copy def ndlist(*args, init=0): dp = init for x in reversed(args): dp = [copy.deepcopy(dp) for _ in range(x)] return dp l = ndlist(1,2,3,4) # 4 dimensional list initialized with 0's l[0][1][2][3] = 1 

Creo que NumPy es el camino a seguir. Lo anterior es genérico si no quieres usar NumPy.

Si desea poder pensarlo como una matriz 2D en lugar de verse obligado a pensar en términos de una lista de listas (mucho más natural en mi opinión), puede hacer lo siguiente:

 import numpy Nx=3; Ny=4 my2Dlist= numpy.zeros((Nx,Ny)).tolist() 

El resultado es una lista (no una matriz NumPy), y puede sobrescribir las posiciones individuales con números, cadenas, lo que sea.

 # Creates a list containing 5 lists initialized to 0 Matrix = [[0]*5]*5 

Tenga cuidado con esta breve expresión, vea la explicación completa en la respuesta de @FJ

¡Para eso está hecho el diccionario !

 matrix = {} 

Puedes definir claves y valores de dos maneras:

 matrix[0,0] = value 

o

 matrix = { (0,0) : value } 

Resultado:

  [ value, value, value, value, value], [ value, value, value, value, value], ... 

Si no tiene información sobre el tamaño antes de comenzar, cree dos listas unidimensionales.

lista 1: para almacenar filas lista 2: matriz bidimensional real

Almacena toda la fila en la 1ra lista. Una vez hecho esto, agregue la lista 1 a la lista 2:

 from random import randint coordinates=[] temp=[] points=int(raw_input("Enter No Of Coordinates >")) for i in range(0,points): randomx=randint(0,1000) randomy=randint(0,1000) temp=[] temp.append(randomx) temp.append(randomy) coordinates.append(temp) print coordinates 

Salida:

 Enter No Of Coordinates >4 [[522, 96], [378, 276], [349, 741], [238, 439]] 

usando la lista:

 matrix_in_python = [['Roy',80,75,85,90,95],['John',75,80,75,85,100],['Dave',80,80,80,90,95]] 

utilizando dict: también puede almacenar esta información en la tabla hash para una búsqueda rápida como

 matrix = { '1':[0,0] , '2':[0,1],'3':[0,2],'4' : [1,0],'5':[1,1],'6':[1,2],'7':[2,0],'8':[2,1],'9':[2,2]}; 

la matriz [‘1’] le dará un resultado en O (1) tiempo

* nb : necesitas lidiar con una colisión en la tabla hash

 l=[[0]*(L) for i in range(W)] 

Será más rápido que:

 l = [[0 for x in range(L)] for y in range(W)] 

Prueba esto:

 rows = int(input('Enter rows\n')) my_list = [] for i in range(rows): my_list.append(list(map(int, input().split()))) 

En caso de que necesite una matriz con números predefinidos, puede usar el siguiente código:

 def matrix(rows, cols, start=0): return [[c + start + r * cols for c in range(cols)] for r in range(rows)] assert matrix(2, 3, 1) == [[1, 2, 3], [4, 5, 6]]