Pregunta Crear listas de listas de forma pitonica


Estoy usando una lista de listas para almacenar una matriz en python. Intenté inicializar una matriz Cero 2x3 de la siguiente manera.

mat=[[0]*2]*3

Sin embargo, cuando cambio el valor de uno de los elementos en la matriz, cambia el valor de esa entrada en cada fila, ya que la identificación de cada fila en mat es el mismo. Por ejemplo, después de asignar

mat[0][0]=1

mat es [[1, 0], [1, 0], [1, 0]].

Sé que puedo crear la matriz cero usando un ciclo de la siguiente manera,

mat=[[0]*2]
for i in range(1,3):
    mat.append([0]*2)

¿pero alguien puede mostrarme una manera más pitonica?


10
2018-05-28 20:50


origen


Respuestas:


Usar una lista de comprensión:

>>> mat = [[0]*2 for x in xrange(3)]
>>> mat[0][0] = 1
>>> mat
[[1, 0], [0, 0], [0, 0]]

O, como una función:

def matrix(rows, cols):
    return [[0]*cols for x in xrange(rows)]

9
2018-05-28 21:00



Prueba esto:

>>> cols = 6
>>> rows = 3
>>> a = [[0]*cols for _ in [0]*rows]
>>> a
[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]
>>> a[0][3] = 2
>>> a
[[0, 0, 0, 2, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]

Esto también se discute en esta respuesta:

>>> lst_2d = [[0] * 3 for i in xrange(3)]
>>> lst_2d
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> lst_2d[0][0] = 5
>>> lst_2d
[[5, 0, 0], [0, 0, 0], [0, 0, 0]]

8
2018-05-28 20:57



¡Este es más rápido que la respuesta aceptada!
Usar xrange (filas) en lugar de [0] * filas no hace diferencia.

>>> from itertools import repeat
>>> rows,cols = 3,6
>>> a=[x[:] for x in repeat([0]*cols,rows)]

Una variación que no usa itertools y corre alrededor de la misma velocidad

>>> a=[x[:] for x in [[0]*cols]*rows]

Desde ipython:

In [1]: from itertools import repeat

In [2]: rows=cols=10

In [3]: timeit a = [[0]*cols for _ in [0]*rows]
10000 loops, best of 3: 17.8 us per loop

In [4]: timeit a=[x[:] for x in repeat([0]*cols,rows)]
100000 loops, best of 3: 12.7 us per loop

In [5]: rows=cols=100

In [6]: timeit a = [[0]*cols for _ in [0]*rows]
1000 loops, best of 3: 368 us per loop

In [7]: timeit a=[x[:] for x in repeat([0]*cols,rows)]
1000 loops, best of 3: 311 us per loop

6
2018-02-25 09:29



yo suelo

mat = [[0 for col in range(3)] for row in range(2)]

aunque dependiendo de lo que hagas con la matriz después de crearla, podrías echarle un vistazo usando una matriz NumPy.


4
2018-05-28 21:03



Esto funcionará

col = 2
row = 3
[[0] * col for row in xrange(row)]

3
2018-05-28 20:59



Qué pasa:

m, n = 2, 3
>>> A = [[0]*m for _ in range(n)]
>>> A
[[0, 0], [0, 0], [0, 0]]
>>> A[0][0] = 1
[[1, 0], [0, 0], [0, 0]]

Aka Lista de comprensión; desde el documentos:

List comprehensions provide a concise way to create lists 
without resorting to use of     
map(), filter() and/or lambda. 
The resulting list definition tends often to be clearer    
than lists built using those constructs.

2
2018-05-28 21:00



Si los tamaños involucrados son realmente solo 2 y 3,

mat = [[0, 0], [0, 0], [0, 0]]

es mejor y aún no ha sido mencionado.


2
2018-01-20 14:26



Ver también esta pregunta para generalización a una lista anidada n / matriz n-dimensional.


1
2018-02-25 08:58