logo

Python | Utilitzant matrius/llistes 2D de la manera correcta

Python proporciona potents estructures de dades anomenades llistes, que poden emmagatzemar i manipular col·leccions d'elements. També ofereix moltes maneres de crear llistes/matrius bidimensionals. Tanmateix, cal conèixer les diferències entre aquestes maneres perquè poden crear complicacions en el codi que poden ser molt difícils de localitzar. En aquest article, explorarem la manera correcta d'utilitzar matrius/llistes 2D a Python.

Utilitzant matrius/llistes 2D de la manera correcta

L'ús de matrius/llistes 2D de la manera correcta implica comprendre l'estructura, accedir als elements i manipular de manera eficient les dades en una graella bidimensional. Quan es treballa amb dades estructurades o quadrícules, les matrius o llistes 2D poden ser útils. Una matriu 2D és essencialment una llista de llistes, que representa una estructura semblant a una taula amb files i columnes.



Creació d'una llista 1-D

A Python, la inicialització d'una col·lecció d'elements en una seqüència lineal requereix la creació d'una matriu 1D, que és un procés fonamental. Tot i que Python no té una estructura de dades integrada anomenada 'matriu 1D', podem utilitzar una llista que pot aconseguir la mateixa funcionalitat. Les llistes de Python són dinàmiques i versàtils, cosa que les converteix en una opció excel·lent per representar matrius 1D. Comencem mirant les maneres habituals de crear una matriu 1d de mida N inicialitzada amb 0s.

Creació de llista 1D utilitzant mètodes naïfs

Inicialitzar i emplenar manualment una llista sense utilitzar cap característiques o construccions avançades a Python es coneix com a crear una llista 1D amb mètodes naïfs.

Python 3








N>=> 5> ar>=> [>0>]>*>N> print>(ar)>

>

>

Sortida

[0, 0, 0, 0, 0]>

Creació de llista 1D mitjançant la comprensió de llistes

Aquí estem multiplicant el nombre de files per la llista buida i, per tant, es crea tota la llista amb cada element zero.

Python 3




N>=> 5> arr>=> [>0> for> i>in> range>(N)]> print>(arr)>

>

>

Sortida

[0, 0, 0, 0, 0]>

Creació d'una llista 2D

L'ús de matrius/llistes 2D de la manera correcta implica comprendre l'estructura, accedir als elements i manipular de manera eficient les dades en una graella bidimensional. En dominar l'ús de matrius 2D, podeu millorar significativament la vostra capacitat per gestionar dades complexes i realitzar diverses operacions de manera eficient.

Creació de llista 2D utilitzant Mètode ingenu

Aquí estem multiplicant el nombre de columnes i, per tant, obtenim la llista 1-D de mida igual al nombre de columnes i, a continuació, la multipliquem amb el nombre de files, la qual cosa resulta en la creació d'una llista 2-D.

Python 3


concat cadena java



rows, cols>=> (>5>,>5>)> arr>=> [[>0>]>*>cols]>*>rows> print>(arr)>

>

>

Sortida

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

Nota: L'ús d'aquest mètode de vegades pot provocar comportaments inesperats. En aquest mètode, cada fila farà referència a la mateixa columna. Això vol dir, fins i tot si actualitzem només un element de la matriu, actualitzarà la mateixa columna de la nostra matriu.

Python




rows, cols>=> (>5>,>5>)> arr>=> [[>0>]>*>cols]>*>rows> print>(arr,>'before'>)> arr[>0>][>0>]>=> 1> # update only one element> print>(arr,>'after'>)>

>

>

Sortida

([[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]], 'before') ([[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]], 'after')>

Creació de llista 1D utilitzant Comprensió de llistes

Aquí estem utilitzant bàsicament el concepte de comprensió de llistes i apliquem un bucle per a una llista dins d'una llista i, per tant, creem una llista 2D.

Python 3


mètode igual a java



rows, cols>=> (>5>,>5>)> arr>=> [[>0> for> i>in> range>(cols)]>for> j>in> range>(rows)]> print>(arr)>

>

>

Sortida

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

Creació de llista 1D utilitzant Llista buida

Aquí estem afegint zeros com a elements per a diverses columnes i després afegint aquesta llista 1-D a la llista de files buides i, per tant, creant la llista 2-D.

Python 3




arr>=>[]> rows, cols>=>5>,>5> for> i>in> range>(rows):> >col>=> []> >for> j>in> range>(cols):> >col.append(>0>)> >arr.append(col)> print>(arr)>

>

>

Sortida

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

Inicialització de la matriu 2D

El codi proporcionat mostra dos enfocaments diferents per inicialitzar una matriu 2D Python . Primer, la matriuarr>s'inicializa mitjançant una comprensió de llista 2D, on cada fila es crea com[0, 0, 0, 0, 0]>. La matriu sencera es crea com una llista de referències a la mateixa llista interna, donant lloc a un àlies. Qualsevol canvi fet a un element d'una fila es reflectirà a totes les files. Aleshores, el codi mostra un altre enfocament que utilitza una comprensió de llista imbricada per crear la matriu 2Darr>. Aquest mètode evita l'àlies creant una llista nova per a cada fila, donant lloc a una matriu 2D adequada.

Python 3




# Python 3 program to demonstrate working> # of method 1 and method 2.> rows, cols>=> (>5>,>5>)> # method 2 1st approach> arr>=> [[>0>]>*>cols]>*>rows> # lets change the first element of the> # first row to 1 and print the array> arr[>0>][>0>]>=> 1> for> row>in> arr:> >print>(row)> # method 2 2nd approach> arr>=> [[>0> for> i>in> range>(cols)]>for> j>in> range>(rows)]> # again in this new array lets change> # the first element of the first row> # to 1 and print the array> arr[>0>][>0>]>=> 1> for> row>in> arr:> >print>(row)>

>

>

Sortida

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

Explicació:

Esperem que només el primer element de la primera fila canviï a 1, però el primer element de cada fila es canvia a 1 al mètode 2a. Aquest funcionament peculiar és perquè Python utilitza llistes poc profundes que intentarem entendre.
Al mètode 1a, Python no crea 5 objectes enters, sinó que només crea un objecte enter, i tots els índexs de la matriu arr apunten al mateix objecte int tal com es mostra.

Si assignem l'índex 0 a un altre nombre enter, per exemple 1, es crea un objecte enter nou amb el valor 1 i, a continuació, l'índex 0 apunta a aquest nou objecte int tal com es mostra a continuació

De la mateixa manera, quan creem una matriu 2d com a arr = [[0]*cols]*files, essencialment estem ampliant l'analogia anterior.

  1. Només es crea un objecte enter.
  2. Es crea una única llista 1d i tots els seus índexs apunten al mateix objecte int al punt 1.
  3. Ara, arr[0], arr[1], arr[2]... arr[n-1] tots apunten al mateix objecte de llista anterior al punt 2.

La configuració anterior es pot visualitzar a la imatge següent.

Ara canviem el primer element de la primera fila d'arr com arr[0][0] = 1

  • arr[0] apunta a l'únic objecte de llista que hem creat més amunt. (Recordeu arr[1], arr[2] ...arr[n-1] també apunten al mateix objecte de llista).
  • L'assignació de arr[0][0] crearà un nou objecte int amb el valor 1 i arr[0][0] ara apuntarà a aquest nou objecte int. (i també ho farà arr[1][0], arr [2][0] … arr[n-1][0])

Això es pot veure clarament a la imatge següent.

Així, quan es creen matrius 2d així, canviar els valors en una determinada fila afectarà totes les files, ja que essencialment només hi ha un objecte enter i només un objecte de llista al qual fan referència totes les files de la matriu.

Com és d'esperar, és difícil rastrejar els errors causats per aquest ús de llistes poc profundes. Per tant, la millor manera de declarar una matriu 2D és

Python 3




rows, cols>=> (>5>,>5>)> print>([[>0> for> i>in> range>(cols)]>for> j>in> range>(rows)])>

>

>

Sortida

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

Aquest mètode crea 5 objectes de llista separats, a diferència del mètode 2a. Una manera de comprovar-ho és utilitzant l'operador 'is' que comprova si els dos operands fan referència al mateix objecte.

transforma cadena a int

Python 3




rows, cols>=> (>5>,>5>)> # method 2 2nd approach> arr>=> [[>0> for> i>in> range>(cols)]>for> j>in> range>(rows)]> # check if arr[0] and arr[1] refer to> # the same object> print>(arr[>0>]>is> arr[>1>])># prints False> # method 2 1st approach> arr>=> [[>0>]>*>cols]>*>rows> # check if arr[0] and arr[1] refer to the same object prints True because there is only one> #list object being created.> print>(arr[>0>]>is> arr[>1>])>

>

>

Sortida

False True>