Zapisz jako PDF

Transkrypt

Zapisz jako PDF
Python dostarcza kilku bardzo użytecznych struktur danych, można wśród nich wyróżnić sekwencje,
w których dane występują w określonym porządku, a do elementów odwołujemy się po indeksach
będących liczbami całkowitymi. Ponadto o każdej strukturze danych możemy powiedzieć, że jest
modyfikowalna lub nie. W przypadku struktur modyfikowalnych możemy zmieniać ich elementy bez
konieczności tworzenia nowych obiektów danej struktury.
Listy
Listy przechowują dane w określonej sekwencji i można je modyfikować w miejscu. Listy mogą
przechowywać elementy różnych typów jak i struktury danych.
Tworzenie listy polega na podaniu jej elementów oddzielonych przecinkiem w nawiasach
kwadratowych:
A = [5, 3.22, 'napis', "AKIA", ['a', 2, 5], {'Ala' : 5, 6 : 'Kot', (1, 2,
3) : 'Smok'}, ('Krowa', 5)]
Można stworzyć pustą listę:
A = []
Listę można również stworzyć z dowolnej sekwencji czy obiektu po którym można się iterować za
pomocą funkcji wbudowanej list:
>>> A = list((1, 2, 3))
>>> A
[1, 2, 3]
>>> A = list("Ala ma kota")
>>> A
['A', 'l', 'a', ' ', 'm', 'a', ' ', 'k', 'o', 't', 'a']
>>> A = list({'a' : 2, 'b' : 3})
>>> A
['a', 'b']
>>> A = list({'a' : 2, 'b' : 3}.iteritems())
>>> A
[('a', 2), ('b', 3)]
>>> A = list({'a' : 2, 'b' : 3}.itervalues())
>>> A
[2, 3]
Do elementów listy dostajemy się dzięki indeksom, zatem aby odczytać k-ty element listy należy
napisać:
A[k]
a aby coś na nim zapisać:
A[k] = 5
W Pythonie elementy listy indeksuje się od 0.
Należy pamiętać, że próba odczytu lub zapisu elementu poza listą skutkuje zgłoszeniem wyjątku:
>>> A[100]
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
A[100]
IndexError: list index out of range
>>> A[100] = 5
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
A[100] = 5
IndexError: list assignment index out of range
Przy pomocy wycinków można odczytywać wiele elementów na raz (wycinki zwracają nową listę
zawierającą pożądane elementy listy pierwotnej), składnia wycinka:
A[a:b:c]
zwraca listę elementów listy A poczynając od elementu o indeksie a, kończąc na elemencie o indeksie
b (ale bez niego) ze skokiem c. Parametr c jest opcjonalny i domyślnie przyjmowana jest wartość 1
(można też pominąć drugi dwukropek). Parametry a i b mogą być ujemne - wtedy pozycja liczona jest
od końca listy, zatem -1 oznacza ostatni element, -2 przedostatni itd. (od ujemnych wartości
dodawana jest długość listy). Jeśli a odpowiada elementowi późniejszemu na liście niż b, a c jest
ujemne to wypisywane są elementy od a do b (bez niego) z krokiem |c|. Parametry a i b też mogą być
pominięte, domyślnie przyjmowane jest a = 0 i b = długość listy (dla c > 0) i a = długość listy i b =
element przed pierwszym elementem (nie da się tego opisać) (dla c < 0). Jeśli parametry wycinek
zwraca listę pustą jeśli parametry a, b i c nie wskazują na żaden element. Sprawdź czy rozumiesz
wszystkie przytoczone poniżej przykłady:
>>> A = [, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> A[:5:2]
[, 2, 4]
>>> A[:5]
[, 1, 2, 3, 4]
>>> A[:5:]
[, 1, 2, 3, 4]
>>> A[3:-2]
[3, 4, 5, 6, 7, 8]
>>> A[-7:-3]
[4, 5, 6, 7]
>>> A[-3:-7:-1] #Zauważ, że nie jest odwróceniem poprzedniego
[8, 7, 6, 5]
>>> A[-4:-8:-1]
[7, 6, 5, 4]
>>> A[5:3:-1]
[5, 4]
>>> A[-3:-7:-2]
[8, 6]
>>> A[:7:3]
[, 3, 6]
>>> A[3::3]
[3, 6, 9]
>>> A[::3]
[, 3, 6, 9]
>>> A[:3]
[, 1, 2]
>>> A[::-3]
[10, 7, 4, 1]
>>> A[:-3]
[, 1, 2, 3, 4, 5, 6, 7]
>>> A[::-1] #Metoda na odwrócenie listy
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ]
>>> A[:] #Metoda na skopiowanie listy
[, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> A[3:5:-1]
[]
>>> A[5:3]
[]
Długość listy można uzyskać dzięki wbudowanej funkcji len. Rozmiar listy można zwiększać o jeden
przed dopisanie na końcu listy elementu przy pomocy metody append, albo doklejenie sekwencji przy
pomocy extend, można także wstawiać element pod dowolny indeks przy pomocy metody insert na
zadaną pozycję przesuwając wszystkie dalsze o jedno miejsce w prawo:
>>> A = [, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> len(A)
11
>>> A.append(11)
>>> A
[, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> A.extend((15, 16))
>>> A
[, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
>>> A.extend("ala")
>>> A
[, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 'a', 'l', 'a']
>>> A.append("ala")
>>> A
[, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 'ala']
>>> A.append([12, 13])
>>> A
[, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 'ala', [12, 13]]
>>> A.append((12, 13))
>>> A
[, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 'ala', [12, 13],
(12, 13)]
>>> A.insert(3, "X") #Pierwszy parametr jest pozycją na którą chcemy wstawić,
a drugi elementem do wstawienia
>>> A
[, 1, 2, 'X', 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 'ala', [12,
13], (12, 13)]
W listach można podmieniać wycinki (jeśli trzeci parametr wycinka nie został podany, lub jest równy
1, to to co chcemy wstawić może mieć inną długość niż wycinek (można to wykorzystać do
kasowania elementów listy), w przeciwnym wypadku długości muszą być zgodne):
>>> A
[, 1, 2, 'X', 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 'ala', [12,
13], (12, 13)]
>>> A[:5] = ["X", "Y", "Z"]
>>> A
['X', 'Y', 'Z', 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 'ala', [12,
13], (12, 13)]
>>> A[:12:-1] = "abcdef"
>>> A
['X', 'Y', 'Z', 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 'f', 'e', 'd', 'c', 'b',
'a']
>>> A[:12:-1] = "abcdefg"
Traceback (most recent call last):
File "<pyshell#101>", line 1, in <module>
A[:12:-1] = "abcdefg"
ValueError: attempt to assign sequence of size 7 to extended slice of size 6
>>> A[:7] = []
>>> A
[8, 9, 10, 11, 12, 13, 'f', 'e', 'd', 'c', 'b', 'a']
Innymi możliwościami usuwania elementów z listy jest użycie następujących metod pop(), która
zwraca i usuwa ostatni element, pop(k) - zwraca i usuwa k-ty element albo remove(elem) - usuwa
pierwszy element równy elem, jeśli nie ma takiego to zwraca wyjątek, lub funkcji wbudowanej del
usuwającej podane elementy:
>>>
[8,
>>>
'a'
>>>
[8,
>>>
12
>>>
[8,
>>>
>>>
[8,
>>>
>>>
[8,
>>>
A
9, 10, 11, 12, 13, 'f', 'e', 'd', 'c', 'b', 'a']
A.pop()
A
9, 10, 11, 12, 13, 'f', 'e', 'd', 'c', 'b']
A.pop(4)
A
9, 10, 11, 13, 'f', 'e', 'd', 'c', 'b']
A.append(11)
A
9, 10, 11, 13, 'f', 'e', 'd', 'c', 'b', 11]
A.remove(11)
A
9, 10, 13, 'f', 'e', 'd', 'c', 'b', 11]
A.remove(12)
Traceback (most recent call last):
File "<pyshell#130>", line 1, in <module>
A.remove(12)
ValueError: list.remove(x): x not in list
>>> del A[5]
>>> A
[8, 9, 10, 13, 'f', 'd', 'c', 'b', 11]
>>> del A[:4]
>>> A
['f', 'd', 'c', 'b', 11]
Możliwe jest sprawdzenie czy element jest na liście przy pomocy operatora in, albo metody index.
Operator in zwraca True lub False, natomiast metoda index pozycję pierwszego elementu równego
zadanemu lub zgłasza wyjątek jeśli nie element nie znajdował się na liście. Do metody index można
podać dwa kolejne opcjonalne parametry definiując zakres indeksów w którym należy szukać. Jeśli
podamy jedną wartość to będziemy szukać wśród indeksów od podanego do końca, jeśli dwie to od
pierwszego do drugiego - 1. Metoda count zliczająca elementy równe danemu:
>>> 'd' in A
True
>>> 'z' in A
False
>>> A.index('b')
3
>>> A.index('z')
Traceback (most recent call last):
File "<pyshell#144>", line 1, in <module>
A.index('z')
ValueError: list.index(x): x not in list
>>> A.count('c')
1
>>> A.index('d', 2) #Po elemencie o indeksie 2 nie ma już 'd'
Traceback (most recent call last):
File "<pyshell#315>", line 1, in <module>
A.index('d', 2)
ValueError: list.index(x): x not in list
>>> A.index('b', 2)
3
>>> A.index('b', 2, 4)
3
Często przydatne jest sortowanie list, można tego dokonać za pomocą metody sort lub funkcji
wbudowanej sorted. Różnica między nimi jest znacząca, gdyż metoda sort dokonuje sortowania w
miejscu (modyfikuje zadaną listę), a funkcja sorted zwraca posortowaną listę. Ponadto do obu funkcji
możemy podać dwa trzy parametry opcjonalne: cmp - funkcję, która będzie używana do
porównywania elementów listy (powinna zwracać -1 jeśli pierwszy element jest mniejszy 0 gdy są
równe i 1 gdy drugi większy), key - funkcję, która zostanie wywołana na każdym elemencie listy i
zostaną one posortowane zgodnie z wynikami tej funkcji i reverse - jeśli będzie True to lista zostanie
posortowana w porządku malejącym:
>>> A = [-5, 10, -2, -1, 17, , 33]
>>> sorted(A)
[-5, -2, -1, , 10, 17, 33]
>>> sorted(A, reverse = True)
[33, 17, 10, , -1, -2, -5]
>>> sorted(A, cmp = lambda x,y: x % 3 < y % 3)
[-5, 10, -2, -1, 17, , 33]
>>> sorted(A, cmp = lambda x,y: cmp(x % 3, y % 3))
[, 33, -5, 10, -2, -1, 17]
>>> sorted(A, key = lambda x: x % 3)
[, 33, -5, 10, -2, -1, 17]
>>> A #Zauważ, że wielokrotne wywołanie sorted nie zmieniło wartości listy
[, 33, -5, -2, 10, -1, 17]
>>> A.sort(reverse = True)
>>> A #Natomiast sort zmienia wartość listy
[33, 17, 10, , -1, -2, -5]
>>> A.sort(cmp = lambda x,y: cmp(x % 3, y % 3))
>>> A
[33, , 10, -2, -5, 17, -1]
Listę w odwróconym porządku można było uzyskać przy pomocy wycinków, można tez tego dokonać
za pomocą funkcji wbudowanej reversed i metody reverse. Funkcja reversed zwraca jednak iterator,
aby na jego podstawie stworzyć listę należy użyć funkcji wbudowanej list:
>>> A
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> A[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> reversed(A)
<listreverseiterator object at 0xb6eb528c>
>>> list(reversed(A))
[9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> A.reverse()
>>> A
[9, 8, 7, 6, 5, 4, 3, 2, 1]
Należy zwrócić szczególną uwagę na fakt, że zmienne w Pythonie są referencjami do miejsc w
pamięci i nie mają one określonych typów. Informacje o typach są trzymane w pamięci razem z
"wartościami" obiektów. Przechowywana jest również liczba referencji do danego obiektu, a gdy
obiekt jest już nieosiągalny przez referencje jest on usuwany z pamięci. Dzięki temu nie musimy
troszczyć się o wycieki pamięci (np. w C czy C++ można było zaalokować pamięć, a następnie
stracić do niej dostęp, co sprawiało, że, aż do zakończenia działania programu nie można było jej
zwolnić i ponownie wykorzystać). Należy też rozróżniać równość dwóch zmiennych i ich tożsamość,
czyli sprawdzanie czy wskazują na dokładnie ten sam obiekt. Tożsamość jest sprawdzana operatorem
is, a równość ==. Fakt, że zmienne są referencjami pociąga za sobą czasami konieczność kopiowania
list, rozważmy poniższy przykład:
>>> A
>>> B
>>> C
>>> B
True
>>> C
True
>>> B
= [1, 2, 3]
= A #B wskazuje na to samo miejsce w pamięci co A
= A[:] #C jest kopią, A, zatem jest równe, ale nie jest tym samym co A
== A
== A
is A
True
>>> C is A
False
>>> A[2] = 'X'
>>> del A[1]
>>> A
[1, 'X']
>>> B
[1, 'X']
>>> C
[1, 2, 3]
Listy można porównywać operatorami <, <=, >, >=, ==, != i is:
>>> A
>>> B
>>> B
True
>>> C
>>> C
True
>>> B
False
= [1, 2, 3]
= [1, 2, 5]
> A
= [1, 2, 3, 4]
> A
<= C
Na przykładzie list można też zaobserwować polimorfizm w Pythonie, otóż operacje dodawania i
mnożenia przez liczbę są przedefiniowane dla list i dodawanie dwóch list to ich konkatenacja, a
mnożenie przez liczbę to wielokrotna konkatenacja zadanej listy. Dostępne są także operatory
skrócone += i *=. Dzięki temu możemy w łatwy sposób przygotować listę odpowiedniej długości do
dalszego wykorzystania:
>>> A
[1, 2, 3]
>>> B
[1, 2, 5]
>>> A + B
[1, 2, 3, 1, 2, 5]
>>> A * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> 3 * A
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> A = [None] * 100
>>> A
[None, None, None, None, None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None,
None, None, None, None, None, None, None,
None, None, None, None, None, None, None,
None, None, None, None, None, None, None,
None, None, None, None, None, None, None,
None, None, None, None, None, None, None,
>>> A += B
>>> A
[1, 2, 3, 1, 2, 5]
>>> A *= 2
>>> A
[1, 2, 3, 1, 2, 5, 1, 2, 3, 1, 2, 5]
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None]
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
Do znajdywania najmniejszego i największego elementu służą funkcje wbudowane min i max, można
do nich podać opcjonalny argument key, który działa analogicznie jak w sort, sumę elementów
można obliczyć za pomocą funkcji sum, można jej podać argument wskazujący początkową wartość:
>>> A
[-1, 2, -5, 10]
>>> min(A)
-5
>>> max(A)
10
>>> min(A, key = lambda x: 1./abs(x))
10
>>> max(A, key = lambda x: 1./abs(x))
-1
>>> sum(A)
6
>>> sum(A, 100)
106
Do generowania list ciągów arytmetycznych przydatna jest funkcja wbudowana range(a, b, c) zwraca ona listę od a do b - 1 z krokiem c, c może być ujemne, jeśli podamy tylko jeden parametr to
otrzymamy listę od 0 do a - 1:
>>> range(5)
[, 1, 2, 3, 4]
>>> range(2, 6)
[2, 3, 4, 5]
>>> range(2, 15, 3)
[2, 5, 8, 11, 14]
>>> range(15, 2, -3)
[15, 12, 9, 6, 3]
Do łączenie elementów listy w napis można użyć funkcji join z biblioteki string, a do dzielenia napisu
funkcji split. Do obu można podać separator jeśli się go nie poda to przyjmowany jest domyślnie biały
znak:
>>> A = ['Ala', 'ma' , 'kota']
>>> napis = "Ala;ma;kota"
>>> import string
>>> string.join(A, ' : ')
'Ala : ma : kota'
>>> string.split(napis, ';')
['Ala', 'ma', 'kota']
>>> string.join(A)
'Ala ma kota'
>>> napis2 = "Ala\tma kota\na nawet dwa"
>>> print napis2
Ala
ma kota
a nawet dwa
>>> string.split(napis2)
['Ala', 'ma', 'kota', 'a', 'nawet', 'dwa']
Z sekwencjami wiążą się też elementy programowania funkcyjnego dostępne w Pythonie. Funkcja
wbudowana filter pozwala wybrać z sekwencji elementy dla których zadana funkcja zwraca True. Z
kolei funkcja map oblicza wyniki zadanej funkcji dla wszystkich elementów sekwencji i zwraca
sekwencję wyników. Funkcja zadana w map może przyjmować wiele argumentów, wtedy należy
podać tyle list ile argumentów i z kolejnych list brane są kolejne argumenty funkcji, gdy któraś lista
się skończy to podstawiane jest None. Funkcja reduce przyjmuje funkcję dwuargumentową
zwracającą pojedynczą wielkość i wywołuje ją kolejno dla dwóch pierwszych elementów sekwencji, a
później dla wyniku i następnego elementu sekwencji i tak aż do skończenia sekwencji uzyskując
ostatecznie pojedynczą wartość. Do funkcji reduce można zadać początkową wartość, wtedy
pierwsze obliczenie jest wykonywane dla tej wartości i pierwszego elementu sekwencji:
>>> A = [-1, 2, -5, 10]
>>> filter(lambda x: x > , A)
[2, 10]
>>> map(lambda x: x**2, A)
[1, 4, 25, 100]
>>> B = [1, 2, 3]
>>> map(lambda x, y: str(x) + str(y), A, B)
['-11', '22', '-53', '10None']
>>> reduce(lambda x, y: x + y, A)
6
>>> reduce(lambda x, y: x + y, A, 200)
206
Bardzo ciekawym sposobem tworzenia list są listy składane, podaje się w nich wyrażenie
reprezentujące elementy tworzonej listy, może zawierać ono wiele zmiennych, następnie dla każdej
zmiennej definiuje się sekwencję z której ona pochodzi i ewentualnie warunki:
>>> A
[-1, 2, -5, 10]
>>> B
[1, 2, 3]
>>> [x**2 for x in A]
[1, 4, 25, 100]
>>> [x + y for x in A for y in B] #Zauważ, że wyniki są obliczane dla każdego
elementu iloczynu kartezjańskiego
[, 1, 2, 3, 4, 5, -4, -3, -2, 11, 12, 13]
>>> [x + y for x in A for y in B if x > y]
[3, 11, 12, 13]
Do przeglądania sekwencji można wykorzystać pętlę for, przydatna bywa też funkcja enumerate(A),
zwracająca listę krotek (indeks, A[indeks]), gdzie A to sekwencja, a indeks przebiega od 0 do len(A) 1 i funkcja zip, której podaje się kilka sekwencji i zwraca ona listę krotek, których kolejne elementy
pochodzą z kolejnych sekwencji, długość wynikowej listy jest równa długości najkrótszej listy:
>>> A = [-1, 2, -5, 10]
>>> B = [, 1]
>>> for x in A:
print x
-1
2
-5
10
>>> for i, x in enumerate(A):
print i, ' ', x
-1
1
2
2
-5
3
10
>>> for (x, y) in zip(A, B):
print x + y
-1
3
Na koniec parę słów o efektywności list. Dostęp do elementu po indeksie, wstawianie jak i usuwanie
elementu z końca listy to operacje wykonywane w czasie stałym (niezależnym od długości listy),
dzięki temu listy dobrze nadają się do implementowania stosu (kolejki FILO - First In Last Out,
struktury danych w której elementy kładziemy na górze stosu i tylko z góry możemy je zdejmować).
Z kolei dodawanie i usuwanie elementów z innych pozycji wymaga już przesunięcia wszystkich
elementów występującym po danym, co sprawia, że listy nie nadają się do implementacji kolejek
FIFO - First In First Out, do takich zadań można wykorzystać strukturę deque z biblioteki
collections, w niej dodawanie i usuwanie z obu końców wykonywane jest w czasie stałym.
Krotki
Krotka to niemodyfikowalna sekwencja. Krotki są bardzo podobne do list, jednak krotki, które nie
zawierają elementów modyfikowalnych mogą być kluczami w słownikach, co jest znaczącą zaletą.
Krotki można tworzyć wprost, przez podanie elementów oddzielonych przecinkami (nawiasy są
opcjonalne):
>>> K = ('Ala', 5, [1, 7], (2, 'A'), {'a' : 'b', (1, 3) : 'c'}) #Ta krotka
nie może być kluczem w słowniku bo zawiera struktury modyfikowalne : listę i
słownik
>>> L = 'Ala', 5, [1, 7], (2, 'A'), {'a' : 'b', (1, 3) : 'c'}
>>> K == L
True
Pustą krotkę tworzy się następująco:
>>> K = ()
>>> K = tuple()
Za to krotkę jednoelementową tworzy się dość nieintuicyjnie - wymagany jest przecinek po
elemencie aby odróżnić krotkę od onawiasowanej wartości:
>>> K = (5) #Teraz K jest liczbą 5, a nie jednoelementową krotką zawierającą
liczbę 5
>>> K
5
>>> K= (5,) #Dopiero to jest jednoelementowa krotka
>>> K
(5,)
>>> K = 5,
>>> K
(5,)
Krotki można też tworzyć na bazie dowolnego obiektu po którym można się iterować przy pomocy
funkcji wbudowanej tuple:
>>> K = tuple({'a' : 1, 'b' : 2}.iteritems())
>>> K
(('a', 1), ('b', 2))
Elementy krotki można przypisać na zmienne:
>>>
>>>
>>>
1
>>>
2
>>>
3
K = (1, 2, 3)
a, b, c = K
a
b
c
Elementy krotek odczytujemy przy pomocy indeksów lub wycinków, dodawanie krotek tworzy nową
krotkę będącą konkatenacją pierwotnych, a mnożenie prze liczbę tworzy krotkę będącą wielokrotną
konkatenacją krotki bazowej. Podobnie jak w przypadku napisów i list krotki można przeglądać przy
pomocy pętli for i posyłać do funkcji reduce, map i filter. Krotki udostępniają metody index i count
działające analogicznie jak w przypadku list. W przypadku krotek możliwe są też porównania
operatorami <=, <, >, >=, == i !=, a także testowanie czy element jest w krotce operatorem in i
sprawdzanie długości funkcją len. Różnica występuje przy tworzeniu krotek składanych, analogiczna
jak w przypadku list konstrukcja zwraca generator i aby uzyskać krotkę konieczne jest wywołanie
tuple:
>>> K = (1, 2, 3)
>>> (x**2 for x in K)
<generator object <genexpr> at 0xb658f9dc>
>>> tuple((x**2 for x in K))
(1, 4, 9)
Słowniki
Słowniki można zaliczyć do kategorii odwzorowań, przechowują one w nieuporządkowany sposób
pary klucz-wartość, z czego klucze muszą być typów niezmiennych (liczby, napisy i krotki
zawierające jedynie typy niezmienne). Klucze muszą być różne, aby jednoznacznie definiowały
wartości.
Pusty słownik tworzy się następująco:
>>> D = {}
>>> D
{}
>>> D = dict()
>>> D
{}
a słownik zawierający elementy za pomocą wymienienia par klucz-wartość po przecinku w nawiasach
wąsatych, przy pomocy funkcji wbudowanej dict, albo kopiując istniejący już słownik metodą copy:
>>> D = {'Ala' : 1, (1, 2, 3) : ['B', 'C'], 1 : "AKIA"}
>>> D
{1: 'AKIA', (1, 2, 3): ['B', 'C'], 'Ala': 1}
>>> D = dict(Ala = 1, Basia = 2)
>>> D
{'Basia': 2, 'Ala': 1}
>>> D = dict((('Ala', 1), ('Basia', 2)))
>>> D
{'Basia': 2, 'Ala': 1}
>>> D = dict([('Ala', 1), ('Basia', 2)])
>>> D
{'Basia': 2, 'Ala': 1}
>>> D = dict({'Basia': 2, 'Ala': 1})
>>> D
{'Basia': 2, 'Ala': 1}
>>> B = D.copy()
>>> B
{'Basia': 2, 'Ala': 1}
Ostatnią metodą tworzenia słowników jest wykorzystanie metody klasowej fromkeys - zwraca ona
słownik z kluczami pochodzącymi z danej sekwencji i wartościami równymi zadanej wartości (jeśli ją
pominiemy to przyjmowane jest None):
>>> dict.fromkeys(['A', 'B', 'C', 'D'])
{'A': None, 'C': None, 'B': None, 'D': None}
>>> dict.fromkeys(['A', 'B', 'C', 'D'], 5)
{'A': 5, 'C': 5, 'B': 5, 'D': 5}
Elementy słownika odczytujemy indeksując po kluczach (jeśli podamy klucz, który nie był w słowniku
zostanie zgłoszony wyjątek), lub wywołując metodę get z podanym kluczem, można podać drugi
parametr i wtedy zostanie on zwrócony w sytuacji gdy klucza nie było w słowniku (domyślnie jest
przyjmowany None). W przeciwieństwie do list słowniki można rozszerzać przez zapisywanie
elementów na klucze dotąd niewystępujące w słowniku. Ostatnią opcją odczytania elementów
słownika jest metoda setdefault, której podajemy klucz i opcjonalnie wartość, która domyślnie jest
przyjmowana None, jeśli klucz był w słowniku to zwracana jest odpowiadająca mu wartość inaczej
jest wstawiana do słownika para klucz-zadana wartość i jest zwracana zadana wartość:
>>> D
{'a' : 1}
>>> D['a']
1
>>> D['z']
Traceback (most recent call last):
File "<pyshell#105>", line 1, in <module>
D['z']
KeyError: 'z'
>>> D.get('a')
1
>>> D.get('z')
>>> D.get('z', 5)
5
>>> D['b'] = 2
>>> D
{'a': 1, 'b': 2}
>>> D.setdefault('z')
>>> D
{'a': 1, 'b': 2, 'z': None}
>>> D.setdefault('a')
1
>>> D.setdefault('zz', 22)
22
>>> D
{'a': 1, 'b': 2, 'z': None, 'zz': 22}
Elementy słownika można usuwać przy pomocy słowa del, a cały słownik można wyczyścić metodą
clear, pewną parę klucz-wartość (nie wiadomo którą) zwraca i usuwa ze słownika metoda popitem(),
a metoda pop(key) zwraca i usuwa ze słownika wartość o kluczu key zgłaszając wyjątek gdy danego
klucza nie ma w słowniku, jeśli podamy dodatkowy parametr, to jest on zwracany zamiast zgłaszania
wyjątku:
>>> D
{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4}
>>> del D['c']
>>> D
{'a': 1, 'b': 2, 'e': 5, 'd': 4}
>>> D.popitem()
('a', 1)
>>> D
{'b': 2, 'e': 5, 'd': 4}
>>> D.pop('b')
2
>>> D.pop('f', 'gg')
'gg'
>>> D
{'e': 5, 'd': 4}
>>> D.clear()
>>> D
{}
Za pomocą operatora in i not in można testować czy dany klucz jest/nie jest w słowniku (można także
użyć metody has_key):
>>> D = {'A': 5, 'C': 5, 'B': 5, 'D': 5}
>>> 'A' in D
True
>>> 'a' in D
False
>>> D.has_key('A')
True
Przy pomocy metody keys można uzyskać listę kluczy, metoda values zwraca listę wartości, a items
listę krotek (klucz, wartość):
>>> D
{'Basia': 2, 'Ala': 1}
>>> D.keys()
['Basia', 'Ala']
>>> D.values()
[2, 1]
>>> D.items()
[('Basia', 2), ('Ala', 1)]
Iteratory do list kluczy, wartości i par klucz-wartość zwracają metody iterkeys, itervalues i iteritems.
Zarówno listy jak i iteratory można wykorzystać w pętli for do przeglądania słownika.
Wielkość słownika można sprawdzić funkcją len.
Do słownika można dodać elementy z innego słownika przy pomocy metody update:
>>> D
{'a': 1, 'b': 2}
>>> D.update({'a' : 3, 'c' : 4}) #Zwróć uwagę, że wartość przypisana do
klucza 'a' uległa zmianie
>>> D
{'a': 3, 'c': 4, 'b': 2}
"Programowanie dla Fizyków Medycznych"

Podobne dokumenty