Historia pytania
Listy (list) to jeden z podstawowych typów danych wbudowanych w Pythonie od pierwszych wersji języka. Z czasem ich wewnętrzna budowa była doskonalona, w szczególności w celu zwiększenia wydajności oraz wygody programowania.
Problem
Ważne jest, aby zrozumieć, że listy w Pythonie są zrealizowane nie jako listy powiązane, ale jako dynamiczne tablice. Błędne wyobrażenie prowadzi do nieefektywnego kodu lub błędnego obliczania złożoności operacji.
Rozwiązanie
Listy są zrealizowane jako dynamiczne tablice, które w razie potrzeby zwiększają rozmiar przydzielonej pamięci „skokowo” (rozszerzając się), aby uniknąć ciągłych kosztów przy dodawaniu elementów. Pozwala to na wstawianie i usuwanie elementów na końcu listy w amortyzowanym czasie O(1). Wstawienie lub usunięcie w środku/początku wymaga przesunięcia elementów, co zajmuje O(n) czasu.
Przykład kodu:
my_list = [1, 2, 3] my_list.append(4) # Dodanie na koniec my_list.insert(1, 'a') # Wstawienie według indeksu print(my_list)
Kluczowe cechy:
Czy można uznać listę w Pythonie za odpowiednik tablicy w C? Jaka jest różnica?
Nie, tablica w C zawiera elementy o stałym typie, umieszczone obok siebie w pamięci. Python list to tablica wskaźników do obiektów, z których każdy odnosi się do niezależnego obiektu dowolnego typu w stercie.
Co się stanie, jeśli będziesz wstawiać elementy na początku listy w pętli? Czy to szybko?
Nie, to wolno: przy wstawianiu na początku (pozycja 0) za każdym razem przesuwane są wszystkie istniejące elementy w prawo. Amortyzowana złożoność — O(n) na operację, dla dużych list prowadzi to do degradacji wydajności.
Jaka jest różnica między operatorami + a append/extend dla list?
lst1 = [1, 2] lst2 = [3, 4] lst3 = lst1 + lst2 # lst3 — nowa lista lst1.append(lst2) # lst1 stanie się [1, 2, [3, 4]] lst1.extend(lst2) # lst1 stanie się [1, 2, 3, 4], jeśli lst1 nie został zresetowany po poprzednim append
W projekcie do przechowywania i stałego usuwania pierwszych elementów używano listy. Zauważono znaczną degradację przy dużej ilości danych.
Zalety:
Wady:
Po zidentyfikowaniu problemu zastąpiliśmy listę collections.deque, który jest zoptymalizowany do takich operacji.
Zalety:
Wady: