Pyton udostępnia potężne struktury danych zwane listami, które umożliwiają przechowywanie kolekcji elementów i manipulowanie nimi. Zapewnia także wiele sposobów tworzenia dwuwymiarowych list/tablic. Należy jednak znać różnice między tymi sposobami, ponieważ mogą one powodować komplikacje w kodzie, które mogą być bardzo trudne do wyśledzenia. W tym artykule przyjrzymy się właściwemu sposobowi używania tablic/list 2D w Pythonie.
Używanie tablic/list 2D we właściwy sposób
Właściwe korzystanie z tablic/list 2D wymaga zrozumienia struktury, dostępu do elementów i wydajnego manipulowania danymi w dwuwymiarowej siatce. Podczas pracy z danymi strukturalnymi lub siatkami przydatne mogą być tablice lub listy 2D. Tablica 2D to w zasadzie lista list, która reprezentuje strukturę przypominającą tabelę z wierszami i kolumnami.
Tworzenie listy 1-D
W Pythonie inicjowanie zbioru elementów w sekwencji liniowej wymaga utworzenia tablicy 1D, co jest procesem podstawowym. Chociaż Python nie ma wbudowanej struktury danych zwanej „tablicą 1D”, możemy użyć listy, która może osiągnąć tę samą funkcjonalność. Listy w języku Python są dynamiczne i wszechstronne, co czyni je doskonałym wyborem do reprezentowania tablic 1D. Zacznijmy od przyjrzenia się powszechnym sposobom tworzenia tablicy 1d o rozmiarze N inicjowanej zerami.
Tworzenie listy 1D metodami naiwnymi
Ręczne inicjowanie i wypełnianie listy bez użycia zaawansowanych funkcji lub konstrukcji w Pythonie jest znane jako tworzenie listy 1D przy użyciu metod naiwnych.
numpy meshgrid
Python3
N>=> 5> ar>=> [>0>]>*>N> print>(ar)> |
>
>
Wyjście
[0, 0, 0, 0, 0]>
Tworzenie listy 1D przy użyciu rozumienia list
Tutaj mnożymy liczbę wierszy przez pustą listę i w ten sposób tworzona jest cała lista z każdym elementem zerowym.
Python3
N>=> 5> arr>=> [>0> for> i>in> range>(N)]> print>(arr)> |
>
>
Wyjście
[0, 0, 0, 0, 0]>
Tworzenie listy 2-D
Właściwe korzystanie z tablic/list 2D wymaga zrozumienia struktury, dostępu do elementów i wydajnego manipulowania danymi w dwuwymiarowej siatce. Opanowując posługiwanie się tablicami 2D, możesz znacznie poprawić swoje umiejętności obsługi złożonych danych i wydajnego wykonywania różnych operacji.
Tworzenie listy 2D za pomocą Metoda naiwna
Tutaj mnożymy liczbę kolumn i w ten sposób otrzymujemy listę 1-D o rozmiarze równym liczbie kolumn, a następnie mnożymy ją przez liczbę wierszy, co skutkuje utworzeniem listy 2-D.
Python3
rows, cols>=> (>5>,>5>)> arr>=> [[>0>]>*>cols]>*>rows> print>(arr)> |
>
>
Wyjście
[[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]]>
Notatka: Użycie tej metody może czasami powodować nieoczekiwane zachowania. W tej metodzie każdy wiersz będzie odwoływać się do tej samej kolumny. Oznacza to, że nawet jeśli zaktualizujemy tylko jeden element tablicy, zaktualizuje on tę samą kolumnę w naszej tablicy.
Pyton
rows, cols>=> (>5>,>5>)> arr>=> [[>0>]>*>cols]>*>rows> print>(arr,>'before'>)> arr[>0>][>0>]>=> 1> # update only one element> print>(arr,>'after'>)> |
porównanie w Javie
>
>
Wyjście
([[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')>
Tworzenie listy 1D za pomocą Rozumienie listy
Tutaj zasadniczo używamy koncepcji rozumienia list i stosujemy pętlę do listy wewnątrz listy, tworząc w ten sposób listę 2-D.
Python3
rows, cols>=> (>5>,>5>)> arr>=> [[>0> for> i>in> range>(cols)]>for> j>in> range>(rows)]> print>(arr)> |
>
>
Wyjście
[[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]]>
Tworzenie listy 1D za pomocą Pusta lista
Tutaj dołączamy zera jako elementy przez określoną liczbę kolumn, a następnie dołączamy tę listę 1-D do pustej listy wierszy, tworząc w ten sposób listę 2-D.
Python3
eol w Pythonie
arr>=>[]> rows, cols>=>5>,>5> for> i>in> range>(rows):> >col>=> []> >for> j>in> range>(cols):> >col.append(>0>)> >arr.append(col)> print>(arr)> |
>
>
Wyjście
[[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]]>
Inicjowanie tablicy 2D
Dostarczony kod demonstruje dwa różne podejścia do inicjowania tablicy 2D w Pyton . Po pierwsze, tablicaarr>jest inicjowany przy użyciu rozumienia list 2D, gdzie każdy wiersz jest tworzony jako[0, 0, 0, 0, 0]>. Cała tablica jest tworzona jako lista odniesień do tej samej listy wewnętrznej, co skutkuje aliasingiem. Wszelkie zmiany wprowadzone w elemencie w jednym wierszu zostaną odzwierciedlone we wszystkich wierszach. Następnie kod przedstawia inne podejście wykorzystujące zrozumienie list zagnieżdżonych do utworzenia tablicy 2Darr>. Ta metoda pozwala uniknąć aliasingu, tworząc nową listę dla każdego wiersza, co skutkuje poprawną tablicą 2D.
Python3
# 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)> |
>
>
Wyjście
[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]>
Wyjaśnienie:
Oczekujemy, że tylko pierwszy element pierwszego wiersza zmieni się na 1, ale pierwszy element każdego wiersza zostanie zmieniony na 1 w metodzie 2a. To szczególne działanie wynika z tego, że Python używa płytkich list, które postaramy się zrozumieć.
W metodzie 1a Python nie tworzy 5 obiektów całkowitych, ale tworzy tylko jeden obiekt całkowity, a wszystkie indeksy tablicy arr wskazują na ten sam obiekt int, jak pokazano.

Jeśli przypiszemy 0-ty indeks do innej liczby całkowitej, powiedzmy 1, wówczas tworzony jest nowy obiekt całkowity o wartości 1, a następnie 0-ty indeks wskazuje teraz na ten nowy obiekt int, jak pokazano poniżej

Podobnie, gdy tworzymy tablicę 2D jako arr = [[0]*cols]*rows, zasadniczo rozszerzamy powyższą analogię.
- Tworzony jest tylko jeden obiekt całkowity.
- Tworzona jest pojedyncza lista 1d, a wszystkie jej indeksy wskazują na ten sam obiekt int w punkcie 1.
- Teraz arr[0], arr[1], arr[2]…. arr[n-1] wszystkie wskazują na ten sam obiekt listy powyżej w punkcie 2.
Powyższą konfigurację można zwizualizować na obrazku poniżej.

Teraz zmieńmy pierwszy element w pierwszym wierszu tablicy jako arr[0][0] = 1
- arr[0] wskazuje na pojedynczy obiekt listy, który utworzyliśmy powyżej. (Pamiętaj, że arr[1], arr[2] …arr[n-1] wszystkie wskazują również na ten sam obiekt listy).
- Przypisanie arr[0][0] spowoduje utworzenie nowego obiektu int o wartości 1, a arr[0][0] będzie teraz wskazywać na ten nowy obiekt int. (podobnie jak arr[1][0], arr [2] [0] … tablica [n-1] [0])
Można to wyraźnie zobaczyć na poniższym obrazku.

Kiedy więc tworzone są tablice 2D w ten sposób, zmiana wartości w określonym wierszu będzie miała wpływ na wszystkie wiersze, ponieważ zasadniczo istnieje tylko jeden obiekt całkowity i tylko jeden obiekt listy, do którego odwołują się wszystkie wiersze tablicy.
Jak można się spodziewać, wyśledzenie błędów spowodowanych takim użyciem płytkich list jest trudne. Dlatego lepszym sposobem na zadeklarowanie tablicy 2d jest
Python3
rows, cols>=> (>5>,>5>)> print>([[>0> for> i>in> range>(cols)]>for> j>in> range>(rows)])> |
>
>
Wyjście
[[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]]>
Ta metoda tworzy 5 oddzielnych obiektów listowych, w przeciwieństwie do metody 2a. Jednym ze sposobów sprawdzenia tego jest użycie operatora „is”, który sprawdza, czy oba operandy odnoszą się do tego samego obiektu.
Python3
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>])> |
prawa równoważności
>
>
Wyjście
False True>