Python | Uso de arreglos/listas 2D de la manera correcta

| | | | | | | | | | | | | | |

Método 1a


# Primera forma de crear una matriz 1D

N = 5

< código clase="simple"> arr = [ 0 ] * N

imprimir (arr)

Salida:

[0, 0, 0, 0, 0] 

Método 1b

# Segunda forma de crear una matriz 1 D

N = 5

arr = [ 0 para i en rango (N)]

imprimir (arr)

Exit:

[0, 0, 0, 0, 0 ] 

Extendiendo lo anterior, podemos definir arreglos bidimensionales de las siguientes maneras.
Método 2a


# Usando el primer método anterior para crear
# matriz 2D

filas, columnas = ( 5 , 5 )

arr = [[ 0 ] * columnas] * filas

< código clase = "funciones"> imprimir (arr)

Salir:

[[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]] 

Método 2b


# Usar el segundo método anterior para crear
# matriz 2D

filas, cols = ( 5 , 5 )

arr < /código> = [[ 0 para i en rango (columnas)] para j < /código> en rango (filas)]

imprimir (arr)

Salida:

[[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]] 

Ambos métodos parecen dar el mismo resultado que ahora. Reemplacemos uno de los elementos en la matriz del método 2a y el método 2b.


# Programa Python 3 para demostrar cómo funciona
# método 1 y método 2.

filas, columnas = ( 5 , 5 )


# método 2a

arr = [[ 0 ] * cols] * filas


# cambiar el primero elemento
# primera línea a 1 e imprime la matriz

arr [ 0 ] [ 0 ] < /código> = 1

para fila en arr:

print (fila)

# genera lo siguiente
# [1, 0, 0, 0, 0]
# [1, 0, 0, 0, 0]
# [1, 0, 0, 0, 0]
# [1, 0, 0, 0, 0]
# [1, 0, 0, 0, 0]


# método 2b

arr = [[ 0 para i en < /código> rango (columnas)] para j en rango (filas)]


# volver a esta nueva matriz le permite cambiar
# primer elemento de la primera fila
# a 1 e imprima la matriz

arr [ 0 ] [ 0 ] < clase de código = "palabra clave"> = 1

para fila en arr:

imprimir (fila)


# genera lo siguiente como se esperaba

# [1, 0, 0, 0, 0]
# [0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0]
# [0, 0, 0, 0, 0]

Salir:

[1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1 , 0, 0 , 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [0, 0, 0, 0 , 0] [ 0, 0, 0, 0, 0] [0, 0, 0, 0, 0] [0, 0, 0, 0, 0] 

Esperamos solo el primer elemento de la primera línea cambiará a 1, pero el primer elemento de cada línea cambiará a 1 en el método 2a. Este tipo de funcionamiento se debe al hecho de que Python usa listas poco profundas, que trataremos de entender.

En el método 1a, Python no crea 5 objetos enteros, sino que solo crea un objeto entero, y todos los índices de la matriz arr apuntan al mismo objeto int que se muestra.


Si asignamos el índice 0 a otro entero, digamos 1, entonces se crea un nuevo objeto entero con el valor 1, y luego el índice 0 ahora apunta a este nuevo objeto int como se muestra a continuación

Del mismo modo, cuando creamos una matriz bidimensional como" arr = [[0] * cols] * fila " , de hecho, estamos ampliando la analogía anterior.
1. Solo se crea un objeto entero.
2. Se crea una lista 1d y todos sus índices apuntan al mismo objeto int en el punto 1.
3. Ahora arr [0], arr [1], arr [2]…. arr [n-1] todos apuntan al mismo objeto de lista anterior en el paso 2.

La configuración anterior se puede visualizar en la imagen a continuación.

Ahora cambiemos el primer elemento en la primera línea" arr "as
arr [0] [0] = 1

=" arr [0] apunta al mismo objeto de lista que creamos arriba (recuerde que arr [1], arr [2]‚Ķ arr [n-1] también apuntan al mismo objeto de lista)
= & gt ; Asignar arr [0] [0] creará un nuevo objeto int con un valor de 1, y arr [0] [0] ahora apuntará a este nuevo objeto int. (Y así será arr [1] [0], arr [2] [0]‚Ķ arr [n-1] [0])

Esto se puede ver claramente en la siguiente imagen .


Entonces, cuando se crean matrices 2d de esta manera, cambiar los valores ‚Äã‚Äãen una determinada línea afectarán a todas las cadenas, ya que esencialmente solo hay un objeto entero y solo un objeto de lista al que hacen referencia todas las filas en la matriz.

Como era de esperar, rastree errores causados por este uso de listas superficiales. Complicado. Por lo tanto, la mejor manera de declarar una matriz 2d es


filas, columnas = ( 5 , 5 )

arr = [[ 0 for i < /código> en rango (columnas)] para j en rango (filas)]

Salir:

 

Este método crea 5 objetos de lista separados a diferencia del método 2a. Una forma de verificar esto — utilice el operador "es", que comprueba si dos operandos se refieren al mismo objeto.


filas, columnas = ( 5 , 5 )

# método 2b

arr < clase de código = "palabra clave"> = [[ 0 para i in rango ( cols)] para j en rango (filas)]


# verificar si arr [0] y arr [1] se refieren a
# mismo objeto

imprimir (arr [ 0 ] es arr [ 1 ] ) # imprime Falso


# método 2a

arr = [[ 0 ] * columnas] < clase de código ="palabra clave"> * filas


# verificar si arr [0] y arr [1] se refieren a
# ese sam e object
# imprime True porque solo hay una
# lista del objeto a crear.

imprimir (arr [ 0 ] es arr [ 1 ])

Salir:

Falso Verdadero