Tablice

Tablice w językach programowania są sposobem przechowywania wielu wartości pod jedną nazwą. W klasycznych językach niskopoziomowych tablica oznacza zwykle ciąg elementów tego samego typu, zapisanych w spójnym obszarze pamięci. W Python sytuacja jest bardziej złożona – pojęcie „tablicy” jest potoczne i obejmuje kilka różnych struktur danych.

W Python podstawowe „tablice” to: listy, krotki i słowniki. Każda z tych struktur ma inną semantykę, inne właściwości i inne zastosowania. Wszystkie należą do kategorii Python: struktury danych wbudowanych w język. W dalszej części tekstu traktuję je jako Tablice, bo pełnią rolę kolekcji elementów.

Tablice Python jako dynamiczne kontenery obiektów – czym są i jak są reprezentowane w pamięci

W Python nie istnieje klasyczna tablica znana z języka C jako int arr[10]. Zamiast tego mamy obiekty dynamiczne. Każda Tablica Python (lista, krotka, słownik) przechowuje referencje do obiektów, a nie same wartości.

To oznacza kilka rzeczy:

  1. Elementy mogą mieć różne typy.
  2. Rozmiar może się zmieniać w trakcie działania programu (dla list i słowników).
  3. Operacje nie zawsze są stałoczasowe – zależy to od implementacji.

W uproszczeniu:

  • Lista → dynamiczna tablica referencji.
  • Krotka → niemodyfikowalna sekwencja referencji.
  • Słownik → tablica mieszająca (hash table).

W odróżnieniu od języka C, Python nie wymaga deklarowania rozmiaru. Zarządzanie pamięcią jest automatyczne.

Tablice – listy w Python jako dynamiczne sekwencje indeksowane liczbami całkowitymi

Lista to najczęściej używana Tablica Python. Jest:

  • uporządkowana,
  • indeksowana od 0,
  • mutowalna (można zmieniać elementy),
  • dynamiczna (rozmiar może się zmieniać).

Tworzenie listy Python – podstawowe sposoby

Najprostsza forma:

a = [1, 2, 3]

Pusta lista:

a = []

Z użyciem konstruktora:

a = list()

Lista z zakresu:

a = list(range(5))

Wynik:

[0, 1, 2, 3, 4]

Dostęp do elementów

a = [10, 20, 30]
print(a[0]) # 10
print(a[-1]) # 30

Indeksowanie ujemne liczy od końca.

Modyfikacja elementów

a = [1, 2, 3]
a[1] = 100

Lista zmieni się na [1, 100, 3].

Odpowiednik w C – klasyczna tablica statyczna

#include <stdio.h>int main() {
int a[3] = {1, 2, 3};
printf("%d\n", a[1]);
return 0;
}

Tutaj:

  • rozmiar jest stały,
  • elementy mają ten sam typ,
  • pamięć jest ciągła.

Odpowiednik w C++ – std::vector jako dynamiczna tablica

#include <iostream>
#include <vector>int main() {
std::vector<int> a = {1, 2, 3};
a.push_back(4);
std::cout << a[0] << std::endl;
return 0;
}

std::vector jest bliższy liście Python niż klasyczna tablica C.

Tworzenie tablic – krotek jako niemodyfikowalnych sekwencji danych

Krotka (tuple) to struktura podobna do listy, ale niemodyfikowalna.

Tworzenie krotki

t = (1, 2, 3)

Jednoelementowa krotka:

t = (5,)

Bez przecinka Python potraktuje to jako zwykłą wartość.

Można też zapisać bez nawiasów:

t = 1, 2, 3

Cechy krotki

  • nie można zmienić elementu,
  • nie można dodać nowego elementu,
  • można ją indeksować jak listę.
t = (10, 20, 30)
print(t[1])

Dlaczego używać krotek

  1. Dane stałe logicznie (np. współrzędne punktu).
  2. Klucze w słownikach.
  3. Optymalizacja – są nieco lżejsze niż listy.

Wewnętrznie krotka nie musi zarządzać nadmiarową przestrzenią jak lista, bo nie zmienia rozmiaru.

Tworzenie tablic – słowników jako struktur klucz-wartość opartych o funkcję mieszającą

Słownik w Python to implementacja tablicy haszującej.

Tworzenie słownika

d = {"a": 1, "b": 2}

Pusty słownik:

d = {}

Z konstruktora:

d = dict()

Dostęp do elementów

print(d["a"])

W słowniku nie używa się indeksów liczbowych, tylko kluczy.

Właściwości

  • klucze muszą być niemodyfikowalne,
  • dostęp do elementu jest średnio O(1),
  • brak gwarancji fizycznego uporządkowania (choć Python zachowuje kolejność wstawiania).

Przykład działania funkcji mieszającej

  1. Klucz → funkcja hash.
  2. Hash → indeks w tablicy.
  3. Kolizje rozwiązywane przez mechanizm wewnętrzny (np. otwarte adresowanie).

Tablice – operacje wspólne dla list i krotek oraz ich znaczenie w przetwarzaniu danych

Sekwencje w Python mają wspólne operacje:

  • długość: len(a)
  • iteracja: for x in a:
    print(x)
  • wycinanie (slicing): a[1:3]

tablica string

W Python łańcuch znaków (str) działa jak niemodyfikowalna sekwencja znaków, czyli jak krotka znaków.

s = "abc"
print(s[0])

To również przykład sekwencji indeksowanej.

Automatyczne uzupełnianie tablic – mechanizmy generowania elementów i inicjalizacji zbiorczej

Automatyczne uzupełnianie tablic oznacza tworzenie struktur na podstawie reguły.

1. List comprehension

a = [x * 2 for x in range(5)]

Wynik:

[0, 2, 4, 6, 8]

Mechanizm:

  • iteracja po sekwencji,
  • obliczenie wyrażenia,
  • zapis do nowej listy.

2. Inicjalizacja powielona

a = [0] * 5

Uwaga: dla obiektów zagnieżdżonych to tworzy referencje do tego samego obiektu.

Błąd:

a = [[0] * 3] * 3
a[0][0] = 9

Zmieni wszystkie wiersze, bo wskazują na ten sam obiekt.

Poprawnie:

a = [[0 for _ in range(3)] for _ in range(3)]

3. Generowanie słowników

d = {x: x*x for x in range(5)}

4. Funkcja enumerate

a = ["a", "b", "c"]for i, v in enumerate(a):
print(i, v)

To częsty element Python: lista komend używanych przy pracy z listami.

Tablice Python a złożoność obliczeniowa podstawowych operacji i ich konsekwencje praktyczne

Lista:

  • dostęp przez indeks: O(1)
  • append: amortyzowane O(1)
  • insert w środku: O(n)
  • usunięcie z początku: O(n)

Słownik:

  • dostęp: średnio O(1)
  • wstawienie: średnio O(1)
  • iteracja: O(n)

Krotka:

  • dostęp: O(1)
  • brak operacji modyfikujących

Przy dużych zbiorach danych różnice stają się istotne.

Python: lista komend i python: komendy lista najczęściej używane przy pracy z listami

Najważniejsze operacje:

a.append(x)
a.insert(i, x)
a.remove(x)
a.pop()
a.sort()
a.reverse()

Sortowanie:

a.sort()

lub

b = sorted(a)

sort() modyfikuje listę, sorted() tworzy nową.

Pułapki i częste błędy przy pracy z tablicami w Python

  1. Mylenie kopii z referencją:
b = a

To nie kopia, tylko druga referencja.

Poprawnie:

b = a.copy()
  1. Modyfikacja listy podczas iteracji.
  2. Używanie listy zamiast słownika przy wyszukiwaniu po kluczu.
  3. Zapominanie o przecinku w jednoelementowej krotce.
  4. Błędne tworzenie wielowymiarowych struktur przez mnożenie list.

Tablice – znaczenie struktur sekwencyjnych i asocjacyjnych w projektowaniu algorytmów

Tablice w Python (listy, krotki, słowniki) są podstawą budowy algorytmów:

  • sortowanie,
  • wyszukiwanie,
  • zliczanie częstości,
  • implementacja stosu i kolejki,
  • reprezentacja grafów (lista sąsiedztwa jako słownik list).

Przykład reprezentacji grafu:

graf = {
1: [2, 3],
2: [4],
3: [],
4: []
}

Tu słownik mapuje wierzchołek na listę sąsiadów.

Zrozumienie, czym są listy, krotki i słowniki, oraz jakie mają właściwości czasowe i semantyczne, jest warunkiem poprawnego projektowania programów w Python. Tablice w tym sensie nie są jedną strukturą, lecz zestawem mechanizmów przechowywania danych, które trzeba dobierać świadomie do konkretnego problemu.