3. Liste¶Sjećate se nizova? Znate, one grupe elemenata istog tipa, fiksne dužine, koje ste koristili kad treba čuvati puno podataka. E pa, liste u Pythonu su jako slične nizovima u drugim programskim jezicim, sa jednom ili dvije "sitne" razlike koje ćemo vidjeti u nastavku. 3.1. Gdje početi?¶Pa, red bi bio da prvo napravimo jednu listu. Kao što joj ime kaže, lista predstavlja listu elemenata ma nije valjda, odvojenih zarezima, a okruženu uglastim zagradama. To bi izgledalo nekako ovako: In [17]:
sadrzajNovcanika = [10, 20, 10, 50, 5, 10] # Pfeninga, ne KM :(
print('Sadržaj novčanika:', sadrzajNovcanika)
komsijeOdKojihKrademWiFi = ['Petrović', 'Galić', 'Čajić', 'Stojaković']
print('Komšije od kojih kradem WiFi:', komsijeOdKojihKrademWiFi)
# Lista može biti i prazna
ljudiPametnijiOdMene = []
print('Ljudi pametniji od mene:', ljudiPametnijiOdMene)
Ako vas slučajno zanima koliko neka lista ima elemenata, funkcija len je sve što vam treba. Poslije ćemo vidjeti da ta funkcija ne radi samo sa listama, već i sa nekim drugim tipovima podataka. In [18]:
mojaLista = [1, 2, 3, 4]
print('Lista', mojaLista, 'je dužine', len(mojaLista))
3.2. Prva razlika: Tipovi elemenata¶Kad sam rekao da su razlike između liste i niza sitne, možda sam malo slagao... Naime, kako tip promjenljive nije fiksan u Pythonu, nema smisla govoriti o listama cijelih brojeva ili listama stringova, kad tip tih elemenata može biti promjenjen. Što nas dovodi do prve razlike između klasičnog niza i Pythonove liste: elementi liste ne moraju biti istog tipa. Iako ovo zvuči mnogo cool, ustvari i nije toliko - postoji jako malen broj problema koji možete riješiti brže i elegantnije tako što ćete stavljati stvari različitog tipa u listu. Za sve ostalo tu je Mastercard? ova osobina i nema nešto velik značaj. In [29]:
mojaMjesovitaLista = [[], 1, 'dva', 3, [4, 5, 6]]
print('Lista raznih elemenata', mojaMjesovitaLista)
oblastiUpotrebe = []
print('Upotrebljava se u', oblastiUpotrebe)
3.3. Pristup elementima¶Elementi liste se obično posmatraju nezavisno jedan od drugog, pa je osnovna operacija koju lista pruža upravo pristup pojedinačnim elementima ili kao što ćemo vidjeti, grupama elemenata. Počnimo onda sa dobrim starim, indeksiranjem. U Pythonu, indeksi niza počinju od 0, tako da se za listu mojaLista prvi elementi nalazi na poziciji 0, a poslednji na poziciji len(mojaLista) - 1. Kao što je to običaj u mnogim programskim jezicima, operator indeksiranja su uglaste zagrade - [ ], a radi otprilike ovako: In [20]:
mojaLista = [14, 8, 7, 12, 11]
mojaLista[0] = 100
print('Zbir prvog i petog je', mojaLista[0] + mojaLista[4])
print('Deseti element:', mojaLista[9])
Prvi dio ispisa je očekivan - dobili smo zbir prvog i petog elementa liste. Drugi dio nije baš najsrećniji - naša lista ima 5 članova, a mi smo htjeli ispisati deseti, što i nema mnogo smisla. Pythonu to takođe nema smisla, pa nas je obradovao sa šarenom porukom "IndexError: list index out of range". 3.3.1. Negativni indeksi¶Pristupanje elementima koji se nalaze na kraju niza često zna biti pipav zadatak - potrebno je naći dužinu niza, pa od nje oduzeti 1 ili treba dodati? jer indeksi kreću od nula, pa onda oduzeti ili ovde treba dodati? redni broj elementa sa desne strane kojem hoćemo da pristupimo. Komplikovana procedura, pa se lako zbuni. Python dozvoljava korištenje negativnih indeksa upravo da riješi ovaj problem. S obzirom da su -0 i 0 isto, poslednji element, odnosno prvi sa desne strane, se nalazi na indeksu -1, onaj prije njega na indeksu -2 i tako dalje. In [21]:
mojaLista = [14, 8, 7, 12, 11]
print('Zbir poslednja dva je', mojaLista[-1] + mojaLista[-2])
# Naravno, kao i sa pozitivnim indeksima, i ovde možete pretjerati
print('Deseti element sa desne strane je', mojaLista[-10])
3.4. Druga razlika: Dodavanje i brisanje elemenata¶U mnogim programskim jezicima, veličina niza je fiksna, te se navodi prilikom njegovog kreiranja, pa ako se preračunate, završićete sa mnogo neiskorištenog prostora ili sa elementima koje ne možete smjestiti u niz. Za razliku od nizova, liste u Pythonu nisu fiksne veličine, već rastu i smanjuju se po potrebi, prilikom dodavanja, odnosno brisanja elemenata. Za dodavanje elemenata, koristićemo metode append, za dodavanje na kraj, odnosno insert, za umetanje elementa na određenu poziciju u nizu. Da bi se napravilo mjesta za element koji se ubacuje u niz, svi elementi koji su desno od novog elementa se "pomjere" za jedno mjesto u desno. Za brisanje bilo kog od elemenata, tu je naredba del. In [22]:
pocetnaLista = [14, 8, 7, 12, 11]
print('Original:', pocetnaLista)
# Dodamo element na kraj
pocetnaLista.append(999)
print('Nakon dodavanja na kraj:', pocetnaLista)
# Umetnemo element na poziciju 2
pocetnaLista.insert(2, 100)
print('Nakon umetanja na poziciju 2:', pocetnaLista)
# Obrišimo ono što smo dodali:
del pocetnaLista[-1] # Element na kraju
del pocetnaLista[2] # Element na poziciji 2
print('Nakon brisanja:', pocetnaLista)
# Ovde ne možemo pretjerati sa indeksima:
# Ako je indeks prevelik, element se dodaje na kraj
# Ako je indeks previše malen, element se dodaje na početak
pocetnaLista.insert(200, 'ja sam na kraju')
pocetnaLista.insert(-50, 'ja sam na pocetku')
print('Konačna lista', pocetnaLista)
3.5. Sjeckanje liste¶Zvanični termin za ovu operaciju je slice, ali pošto sliceovanje i slajsovanje zvuče malo, nakaradno, zadržaćemo se na sjeckanju. Operacija je jednostavna - iz liste isjeći određen dio. Kad će mi to trebati? Pa recimo:
Slično indeksiranju, koristi se operator [ ], ali ovaj put ne navodimo jedan broj, već dva, koje predstavljaju granice onog što želimo da isječemo, a odvojene sa dvotačkom ( : ). Mnogo bitno za napomenuti, sječenje uzima sve element počev od prvog, do ali ne uključujući poslednjeg. Za razliku od indeksiranja, rezultat sječenja je uvijek lista, koja u zavisnosti od granica sječenja može biti prazna, imati jedan ili više elemenata. In [23]:
pocetnaLista = [14, 8, 7, 12, 11]
print('Prva tri elementa', pocetnaLista[0:3])
print('Svi elementi osim poslednjeg', pocetnaLista[0:-1])
# Iako je rezultat samo jedan element, sječenje vraća niz!
print('Samo prvi element', pocetnaLista[0:1])
# Ili nekad prazan
print('Nepostojeći isječak', pocetnaLista[100:120])
S obzirom da često želimo prvih nekoliko ili poslednjih nekoliko elemenata, postoji nekoliko skraćenica:
In [24]:
pocetnaLista = [14, 8, 7, 12, 11]
print('Prva dva elementa', pocetnaLista[:2])
print('Poslednja dva elementa', pocetnaLista[-2:])
# Kopiraj listu
kopijaListe = pocetnaLista[:]
# Obriši poslednji
del kopijaListe[-1]
print('Original', pocetnaLista)
print('Izmjenjena', kopijaListe)
3.5.1. Zamjena isječka¶Sjeckanje liste omogućava ne samo pristup određenom dijelu liste za čitanje, već taj dio možemo i mijenjati. Ono čime mijenjamo isječak jeste nova lista (ne mora biti iste dužine kao isječak), a rezultat je originalna lista, gdje je isječak zamjenjen novom listom. Mala napomena - ovo se ne odnosi na odsječak liste koji ste dodijelili nekoj promjenljivoj, pa onda tu promjenljivu mijenjali. Odnosi se isključivo na direktnu dodjelu isječku. Primjer: In [25]:
# Zamjena je iste dužine
mojaLista = [1, 2, 100, 200, 5, 6]
mojaLista[2:4] = [3, 4]
print('Zamjena iste dužine', mojaLista)
# Zamjena je kraća
mojaLista = [1, 2, 100, 200, 5, 6]
mojaLista[2:4] = []
print('Zamjena kraćom listom', mojaLista)
# Zamjena je duža
mojaLista = [1, 2, 100, 200, 5, 6]
mojaLista[2:4] = [3, 3.25, 3.5, 3.75, 4]
print('Zamjena dužom listom', mojaLista)
# Ovo ne radi (pokušaj primjera iznad)
mojaLista = [1, 2, 100, 200, 5, 6]
promjenljiva = mojaLista[2:4]
promjenljiva = [3, 3.25, 3.5, 3.75, 4]
print('Zamjena dužom listom (pokušaj)', mojaLista)
3.5.2. Korak¶Iako sjeckanje liste omogućava da isječemo dio koji nas zanima, ograničeni smo činjenicom da možemo isjeći samo nekoliko uzastopnih elemenata. Šta ako vas zanima svaki stoti kupac, svaki treći zadatak? Potpuna sintaksa za sjeckanje liste jeste operator indeksiranja [ ], u kojem se navode tri broja, odvojena dvotačkama ( : ). Prva dva smo do sad vidjeli - početak isječka i njegov kraj. Onaj treći nam govori da li uzimamo svaki element, svaki drugi, svaki peti i slično. Ako se ne navede on, ili se izostavi druga dvotačka, podrazumijeva se da je njegova vrijednost 1. Kao i kod indeksa, niko nas ne primora da stavimo pozitivan broj. Evo kako to izgleda u praksi: In [26]:
mojaLista = [1, 2, 100, 200, 5, 6]
print('Elementi na neparnim indeksima', mojaLista[::2])
print('Elementi na parnim indeksima', mojaLista[1::2])
# Najčešća primjena negativnog indeksa - okretanje liste
print('Okrenuta lista', mojaLista[::-1])
# Dodjeljivanje takođe radi ...
mojaLista[::2] = [0, 0, 0]
print('Dodjela neparnim indeksima', mojaLista)
# ... ali samo kad nova lista ima isto elemenata koliko i isječak
mojaLista[1::2] = [0]
|
||||||||
|