https://docs.python.org/3/library/stdtypes.html#lists
Listy to uporządkowane kolekcje dowolnych obiektów. Są heterogeniczne i mogą być dowolnie zagnieżdżane. Dostęp do obiektów możliwy jest za pomocą offsetu (położenia na liście).
Listy mogą się rozrastać i kurczyć w miejscu, czyli są zmiennymi (mutable) sekwencjami. Z technicznego punktu widzenia, listy Pythona zawierają zero lub więcej odwołań do innych obiektów. Listy obsługują zagnieżdżanie obiektów na dowolną głębokość.
Jeżeli potrzebujemy częstego wyszukiwania elementów na liście, to lepiej zastosować słowniki lub zbiory.
+----------------------+-----------------------------+ | Operacja | Znaczenie | +----------------------+-----------------------------+ | L = [] ; L = list() | lista pusta | | L = [5, 1.2] | lista dwupozycyjna | | L = list(iterable) | tworzenie listy z iterable | | len(L) | rozmiar (długość) | | L1 + L2 | łączenie | | L * n ; n * L | powtarzanie | | L[i] | indeks | | L[i:j] | wycinek (nowa lista) | | L[i:j:k] | wycinek (nowa lista) | | L[i] = item | nowy element na liście | | L1[i:j] = L2 | podstawienie pod wycinek | | L2 = L1[:] | kopiowanie płytkie | | L2 = list(L1) | kopiowanie płytkie | | L2 = L1.copy() | kopiowanie płytkie (Py3.3+) | | for item in L: pass | iteracja | | item in L | zawieranie (linear-time) | | item not in L | | | max(L), min(L) | największy|najmniejszy | | del L[i] | usuwanie elementu z listy | | del L[i:j] | usuwanie wycinka | | del L[:] | czyszczenie listy | | L.clear() | czyszczenie listy (Py3.3+) | | del L | usuwanie listy (zmiennej L) | +----------------------+-----------------------------+
list1 = [10, 20, 30, 40, 50, 60] # list1 = [10, 20, 30, 40, 50, 60,] # przecinek na końcu jest dozwolony list2 = ["abc", "d", "ef", "g", "hij"] list3 = [3, "xyz", [10, 20]] # listy są heterogeniczne # Elementy listy można uaktualniać. list2[1] = "xyz" # pojedynczy element list2[2:4] = ["2", "3"] # podmiana wycinka print ( list2 ) alist = list(range(10)) alist[4:4] = [1, 1, 1] # wstawianie PRZED elementem o indeksie 4 alist[2:4] = [] # usuwanie elementów o indeksach 2, 3 # Bardziej przejrzyste jest korzystanie z del. # del alist[2:4] # Można też usunąć całą listę. # del alist
>>> a = [1, 2, 3] >>> b = a >>> del a # usuwanie referencji do obiektu listy >>> b [1, 2, 3]
>>> a = [1, 2, 3] >>> b = a >>> a = [] # podstawienie nowej referencji >>> b [1, 2, 3]
>>> a = [1,2,3] >>> b = a >>> del a[:] # czyszczenie wycinka in place, podobnie dla a.clear() >>> a [] >>> b []
Przy kopiowaniu list trzeba pamiętać o sposobie działania instrukcji podstawiania.
L1 = [12, 13, 14] L2 = L1 # kopiowanie referencji do listy L1 is L2 # True, id(L1) jest równe id(L2) L3 = L1[:] # kopia przez operator zakresu, powstaje nowa lista L4 = list(L1) # jeszcze prościej
https://www.youtube.com/watch?v=XjOnY-OLAPc
Quicksort, Timsort, Powersort - PyCon US 2023 talk
Listy mają wbudowaną metodę do sortowania elementów w miejscu. Przez prawie 20 lat Python wykorzystywał algorytm sortowania stabilnego Timsort, którego autorem jest Tim Peters (Py2.3 - Py3.10). W Pythonie 3.11 pojawił się nowy algorytm sortowania stabilnego Powersort, którego autorem jest Sebastian Wild. W algorytmie Timsort zmieniono politykę łączenia podsekwencji, w celu przyspieszenia algorytmu. Wcześniej poprawiono w algorytmie Timsort pewien błąd, który ujawnił się po raz pierwszy w języku Java.
# help(list.sort) # L.sort(cmp=None, key=None, reverse=False) # Py2 # L.sort(None, None, True) # dozwolone tylko w Py2 (bez słów kluczowych) # L.sort(/, *, key=None, reverse=False) # Py3, keywords only # Sortowanie stabilne IN PLACE. # Funkcja cmp(x, y) ma zwracać jedną wartość z (-1, 0, 1). alist = ["auto", "Ala", "bocian", "Barbara"] alist.sort() # sortowanie listy napisów (duże litery najpierw) print(alist) # ['Ala', 'Barbara', 'auto', 'bocian'] # Potrzebujemy case-insensitive sort. # Stary sposób - określamy funkcję porównującą dwa obiekty. # Bazujemy na wbudowanej funkcji porównującej cmp(). alist.sort(cmp=lambda x,y: cmp(x.lower(), y.lower())) print(alist) # ['Ala', 'auto', 'Barbara', 'bocian'] # Nowy sposób (Py2.4+) - podajemy klucz, czyli jakby sposób # patrzenia na obiekt. Nazwa "str" występuje jako nazwa klasy. # Sortowanie jest stabilne. alist.sort(key=str.lower) # Sortowanie pod względem długości napisów. alist.sort(key=len) print(alist) # ['Ala', 'auto', 'bocian', 'Barbara']
Prosty sposób sortowania to wykorzystanie wbudowanej funkcji sorted(), która zwraca nową, posortowaną listę (oryginalna lista pozostaje niezmieniona). Korzysta ona z metody specjalnej __lt__ i może być używana nie tylko dla list, ale ogólnie dla obiektów iterowanych. sorted() pozwala na sortowanie niezmiennych sekwencji.
# help(sorted) # sorted(iterable, cmp=None, key=None, reverse=False) # Py2 # sorted(iterable, /, *, key=None, reverse=False) # Py3 # Zwraca nową posortowaną listę. sorted("dacb") # ['a', 'b', 'c', 'd'] sortowanie znaków sorted((7,2,5,3)) # [2, 3, 5, 7] sortowanie krotki # Działanie funkcji sorted() możemy zasymulować za pomocą funkcji. def mysorted(iterable): alist = list(iterable) alist.sort() return alist
Przy sortowaniu krotek przydaje się konstrukcja z modułu operator.
# https://docs.python.org/2/library/operator.html import operator # Py2.4+ # Sortowanie IN PLACE krotek wg wartości pola o indeksie 1. alist = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)] alist.sort(key=operator.itemgetter(1)) # [('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)] # Można też utworzyć nowa listę. blist = sorted(alist, key=operator.itemgetter(1))
W Pythonie często możemy zobaczyć wyrażenia typu obiekt.metoda(argumenty). Nawiązuje to do programowania obiektowego. Metoda jest funkcją, która należy do obiektu i nosi pełną nazwę obiekt.metoda(). Obiekt innego typu może posiadać metodę o tej samej nazwie, np. obiekt2.metoda(), ale nie prowadzi to do dwuznaczności. Mamy również konstrukcje typu obiekt.atrybut i również różne obiekty mogą mieć atrybut o tej samej nazwie, ale niekonieznie tym samym typie.
dir(list) # spis metod i atrybutów dla list L = ["a", "a", "a", "b", "b"] L.count("a") # 3, liczba wystąpień "a" na liście L.append("c") # dołączenie "c" na koniec listy print(L) # ['a', 'a', 'a', 'b', 'b', 'c'] L.insert(1, "x") # dołączenie przed indeksem 1 print(L) # ['a', 'x', 'a', 'a', 'b', 'b', 'c'] L.remove("a") # usuwanie wskazanego elementu - pierwsze wystąpienie print(L) # ['x', 'a', 'a', 'b', 'b', 'c'] L.pop() # "c", usuwanie od końca (błąd dla pustej listy) L.pop(2) # "a", usuwanie elementu nr 2 - zwraca element print(L) # ['x', 'a', 'b', 'b'] L.reverse() # odwracanie listy IN PLACE print(L) # ['b', 'b', 'a', 'x'] # L.index(x[, i[, j]]) # indeks x od i, a przed j L.index("a") # 2, jaki indeks ma "a" L.extend("qwerty") # L.extend(iterable), dołączyć nowe elementy print(L) # ['b', 'b', 'a', 'x', 'q', 'w', 'e', 'r', 't', 'y']
List comprehensions, czyli listy składane
są elementami programowania funkcyjnego, przejętymi z języka Haskell.
Jest to zwarty sposób na tworzenie list bez odwoływania się
do map(), filter(), czy wyrażeń lambda.
Kolejność elementów w nawiasie kwadratowym:
wyrażenie, pętla for, dalej wielokrotnie (opcjonalnie)
pętla for lub wyrażenie warunkowe if.
Listy składane często pozwalają uzyskać dużą szybkość przetwarzania,
jak kod w języku C.
Należy zachować umiar przy tworzeniu zagnieżdżonych list składanych,
często bardziej czytelne są zwykłe pętle wielokrotne.
Składnia list składanych przenosi się w dużej mierze na generatory, czyli "leniwe" funkcje zwracające pojedyńczą wartość na żądanie. Generatory można również tworzyć za pomocą wyrażenia yield. Więcej wyjaśnień zostanie podanych przy funkcjach.
[x for x in "qwerty"] # ['q', 'w', 'e', 'r', 't', 'y'], jak list("qwerty") [x * x for x in range(6)] # [0, 1, 4, 9, 16, 25] [3 * x for x in range(6) if x < 4] # [0, 3, 6, 9] [2 ** x for x in range(5)] # [1, 2, 4, 8, 16] [[x, x * x] for x in range(6)] # lista list [(x, x * x * x) for x in range(6)] # przy krotkach wymagane nawiasy [chr(x) for x in range(97, 110)] "".join([chr(x) for x in range(97, 110)]) # sklejamy listę [x + y for x in range(3) for y in range(4)] [(x, y) for x in range(3) for y in range(4)] [x for x in range(2) for y in range(4)] # [0, 0, 0, 0, 1, 1, 1, 1] [y for x in range(2) for y in range(4)] # [0, 1, 2, 3, 0, 1, 2, 3] [c for s in ("aa","b","ccc") for c in s] # ['a', 'a', 'b', 'c', 'c', 'c'] sum([x * x for x in range(100)]) # pełna lista sum(x * x for x in range(100)) # generator sum(len(x) for x in ["a", "bb", "ccc"]) # generator max(ord(x) for x in "qwerty") # największy numer max("qwerty", key=ord) # znak o największym numerze