Jason. Cała informatyka w jednym miejscu!

Dzisiaj trudny temat języka Python. Prezentacja jak wyglądają tablice dwuwymiarowe oraz jak wygląda prawidłowe ich programowanie. Sprawdźcie sami do czego one służą, jak je rozumieć oraz jak się po nich poruszać w kodzie źródłowym. Zapraszam!

TABLICE DWUWYMIAROWE BARDZIEJ ABSTRAKCYJNIE

Przez cały artykuł będę korzystać ze słowa "tablica" mimo tego, że w Pythonie nie ma tablic, w rozumieniu tych samych tablic występujących chociażby w języku Java. Choćby z tego względu, że tutaj dopuszczalne jest przechowywanie w jednym kontenerze elementów o różnych typach danych. Aby już nie kłócić się czy to tablica, czy kolekcja, podjąłem decyzję o trzymaniu się już słowa "tablica".

"NA CHŁOPSKI ROZUM"

Tablica w tablicy to najprościej rzecz ujmując kształt tabelki czy planszy. Każde zagnieżdżenie tworzy kolejny wymiar i przez to tablice dwuwymiarowe najczęściej porównuje się do wymienionych przykładów. Kolumny to oś X, wiersze to oś Y. Tyle od strony teoretycznej!

Schemat tablicy dwuwymiarowej

Tablice dwuwymiarowe, czyli jedne tablice w drugich tablicach, można porównać do budowy tabeli czy planszy, gdyż zawsze jest znana długość obu wymiarów (X oraz Y).

WYSTĘPOWANIE W KODZIE

A teraz część "bardziej serio". Zastanówmy się jak to może wyglądać "kodowo". Wiemy z artykułu o pętli "for" jak wygląda pojedynczy wymiar:

words = ["Programowanie", "w", "Pythonie", "jest", "łatwiejsze"]

Czyli mówiąc wygodniej, mamy jeden wiersz i N kolumn (w zależności od tego, ile znajduje się argumentów). Dlatego też wystarczyło zrobić jedną pętlę "while" bądź "for" do "przelatywania" przez wszystkie elementy, tak?

Popatrzmy teraz na coś takiego:

table = [
    ["A", "B", "C"],
    ["D", "E", "F"],
    ["G", "H", "I"]
]

Tak wyglądają tablice dwuwymiarowe. Celowo zapisałem to w takiej postaci, abyście mogli lepiej na to spojrzeć. Czy dwie pętle załatwią sprawę? Średnio. Co widzimy na powyższym przykładzie? Trzy mniejsze tablice wewnątrz tej "zewnętrznej". Innymi słowy, celem dostania się do wartości, musimy do tablicy "wejść podwójnie"Zatem, wniosek nasuwa się tylko jeden.

ZAGNIEŻDŻANIE PĘTLI

Oznaczmy sobie literą A liczbę wierszy, a liczbę kolumn będzie reprezentować litera B. Aby prawidłowo przemieszczać się po tablicach dwuwymiarowych, musimy zaopatrzyć się w dwie pętle. Co więcej, musimy "włożyć" jedną do drugiej tworząc w ten sposób zagnieżdżenie. Jest to niezbędny zabieg, ponieważ każda iteracja będzie powodować "przeskok" do następnej komórki. Jak napisałem wyżej, tak tablice dwuwymiarowe są skonstruowane. Skoro mamy dwa wymiary, to musimy przejść przez A*B iteracji, czyli iloczyn wierszy i kolumn.

Zagnieżdżona pętla "for" w Pythonie Działanie zagnieżdżonej pętli "for" w Pythonie

Tablice dwuwymiarowe wymagają użycia zagnieżdżonych pętli, aby móc prawidłowo obsłużyć każdą komórkę.

Gdy zrozumiecie ten manewr, nic Wam nie stanie na przeszkodzie, aby robić tablice sięgające trzech czy jeszcze więcej wymiarów!

"FOR" KONTRA "WHILE"

Skonfrontujmy sobie teraz obie pętle dążące do tego samego rozwiązania. Zacznijmy od pętli "for". Pamiętacie co o nich pisałem? Najlepsze wykorzystanie mają w sytuacjach, w których WIEMY ile razy muszą się wykonać pożądane instrukcje. Tablice dwuwymiarowe jak najbardziej pasują do tego przypadku. Wykorzystując powyższy przykład, możemy zapisać to w taki sposób:

table = [
    ["A", "B", "C"],
    ["D", "E", "F"],
    ["G", "H", "I"]
]

for t in table:
    for e in t:
        # dalsze instrukcje

Jak widzicie, pierwsza pętla "for" odpowiada za "wejście" do tablicy, w której zmienna oznaczona literką "t" reprezentuje pierwszy wiersz (albo rząd nazywany zamiennie), czyli:

["A", "B", "C"]

W środku niej widzicie bezsprzecznie drugą pętlę "for", która ona z kolei posiada zmienną "e" oznaczającą pojedynczy element, ale nie całej tablicy, tylko tego pierwszego rzędu. Teraz powinniście kapować jak to się zachowuje. Tłumacząc krok po kroku:

  1. pierwsza pętla wejdzie do pierwszego rzędu,
  2. druga pętla wejdzie do pierwszego elementu pierwszego rzędu,
  3. druga pętla wejdzie do drugiego elementu pierwszego rzędu,
  4. druga pętla wejdzie do trzeciego elementu pierwszego rzędu,
  5. pierwsza pętla wejdzie do drugiego rzędu,
  6. druga pętla wejdzie do pierwszego elementu drugiego rzędu...

I tak dalej. A co w przypadku pętli "while", która nie udostępnia żadnych zmiennych iteracyjnych? Sprawa już wygląda na dużo bardziej skomplikowaną:

table = [
    ["A", "B", "C"],
    ["D", "E", "F"],
    ["G", "H", "I"]
]

row = 0

while row < len(table):
    column = 0
    current_row = table[row]

    while column < len(current_row):
        # dalsze instrukcje

        column += 1

    row += 1

Musimy się "uzbroić" w dwie zmienne, które będą ustawiać obecny rząd i kolumnę. Jedna na zewnątrz, gdyż odpowiada za warunek wejścia zewnętrznej pętli, a druga już może być pomiędzy, ponieważ staje się istotna wyłącznie dla wewnętrznej pętli "while". Spróbujcie sami pogłówkować dlaczego :). Trudne może być do zapamiętania w którym miejscu powinna wystąpić inkrementacja obu liczników. Wystarczy zauważyć kiedy działanie odpowiedniej pętli dobiega końca i dorzucić instrukcję +1 jako ostatnią w kolejności. Tuż przed zwiększeniem licznika kolumn, robimy swoje jak poprzednio.

Domyślam się którą ścieżką poszłaby zdecydowana większość z Was :D. Porównajcie sobie te kody pod względem skomplikowania i liczby linijek celem osiągnięcia tego samego.

ZASTOSOWANIE

Ostatnie słowa poświęcę na zastosowanie. Tablice dwuwymiarowe najlepiej sprawdzają się w sytuacjach, gdy dany problem wymaga takiego "rozłożenia" elementów, jakbyśmy kładli je na dwuwymiarowej powierzchni. Tabelka danych, plansza do gry czy też od biedy współrzędne na każdy wymiar. To są najczęstsze i najbardziej intuicyjne przypadki.


Tyle widziałbym prezentacji. Im szybciej zrozumiecie dlaczego takie zagnieżdżanie jest potrzebne, tym szybciej Wam przyjdzie do głowy wtłaczanie pętli dla większej liczby wymiarów ;).

PODOBNE ARTYKUŁY