Nizi#

V programih seveda ne delamo le s števili, temveč tudi z drugimi podatki, na primer besedili. V ta namen Python podpira nize, ki so strnjena zaporedja znakov. Nize običajno pišemo v enojnih narekovajih, na primer 'to je primer niza'.

Osnovne operacije na nizih#

Nize lahko stikamo z operacijo + in množimo s celimi števili:

'zala' + 'gasper'
'zalagasper'
'tro' + 4 * 'lo'
'trololololo'

Dolžino niza dobimo s funkcijo len:

len('lokomotiva')
10

Pogosto uporabljana funkcija je tudi str, ki dano vrednost pretvori v niz z njeno predstavitvijo:

str(110)
'110'

Nize lahko med seboj tudi primerjamo. Pri tem Python nize ureja leksikografsko, torej tako, kot bi bili urejeni v leksikonu ali kazalu: najprej primerja prvi črki, če sta ti dve enaki, pogleda drugi dve, in tako naprej. Pri tem velike črke pridejo na vrsto pred malimi, na šumnike pa se brez posebnih knjižnic Python ne spozna.

'beseda' == 'konj'
False
'abak' <= 'abeceda'
True

Na nizih imamo na voljo tudi predikat in, s katerim ugotovimo, ali se nek niz pojavlja kot podniz v drugem nizu. Na voljo je tudi not in, s katerim bolj berljivo zapišemo ravno nasprotno stvar:

'gram' in 'Uvod v programiranje'
True
'liter' in 'Uvod v programiranje'
False
not ('liter' in 'Uvod v programiranje')
True
'liter' not in 'Uvod v programiranje'
True

Indeksi in rezine#

Do posameznega znaka v nizu pridemo z indeksi. Z izrazom niz[i] dostopamo do i-tega znaka v danem nizu:

'REKURZIJA'[3]
'U'
'REKURZIJA'[0]
'R'
'REKURZIJA'[-1]
'A'

Indeksi se začnejo šteti z 0. Če uporabimo negativna števila, lahko štejemo tudi od zadaj, vendar tam začnemo šteti z -1 (saj je -0 = 0).

\ 0   1   2   3   4   5   6   7   8
 R   E   K   U   R   Z   I   J   A
-9  -8  -7  -6  -5  -4  -3  -2  -1

Na podoben način lahko dostopamo tudi do podnizov. Če napišemo niz[i:j] bomo dobili niz, ki mu pravimo rezina in sega od vključno i-tega do vključno j - 1-tega znaka. Če kakšno od meja izpustimo, bomo vzeli vse znake od začetka oziroma do konca.

'REKURZIJA'[2]
'K'
'REKURZIJA'[6]
'I'
'REKURZIJA'[2:6]
'KURZ'
'REKURZIJA'[:6]
'REKURZ'
'REKURZIJA'[2:]
'KURZIJA'

Pišemo lahko tudi niz[i:j:k], s čimer vzamemo le vsak k-ti znak:

'REKURZIJA'[1:8]
'EKURZIJ'
'REKURZIJA'[1:8:1]
'EKURZIJ'
'REKURZIJA'[1:8:2]
'EUZJ'
'REKURZIJA'[1:8:3]
'ERJ'
'REKURZIJA'[::-1]
'AJIZRUKER'

S pomočjo indeksov in rezin lahko napišemo (ne najbolj učinkovito) funkcijo, ki prešteje vse samoglasnike v danem nizu:

def stevilo_samoglasnikov(niz):
    if niz == '':
        return 0
    elif niz[0] in 'aeiouAEIOU':
        return 1 + stevilo_samoglasnikov(niz[1:])
    else:
        return stevilo_samoglasnikov(niz[1:])

stevilo_samoglasnikov('Uvod v programiranje')
7

Funkcija deluje tako, da najprej pogleda, če je niz prazen. Če je, v njem ni samoglasnikov, zato vrne 0. Če ni, pogleda prvi znak. Če je samoglasnik, potem je število samoglasnikov za ena večje od števila samoglasnikov v preostanku niza (ki ga dobimo s pomočjo rezine), sicer pa je enako številu samoglasnikov v preostanku.

Zapisi nizov#

Nize lahko pišemo tudi z dvojnimi narekovaji, ki jih ponavadi uporabimo takrat, kadar v nizu želimo uporabiti enojni narekovaj: "Tole je kr'neki!". V tem primeru niza ne moremo pisati med enojnimi narekovaji, saj bi Python po narekovaju za kr mislil, da je konec niza.

'Tole je kr'neki!'
  Cell In[25], line 1
    'Tole je kr'neki!'
                     ^
SyntaxError: unterminated string literal (detected at line 1)

Včasih želimo uporabiti obe vrsti narekovajev. V tem primeru si pomagamo z ubežnimi znaki. To so znaki, ki jih na običajni način ne moremo zapisati, zato uporabimo poseben zapis, ki se začne z znakom \. Tedaj lahko pišemo '"Tole je kr\'neki," je rekla.' ali pa "\"Tole je kr'neki,\" je rekla.\". Ubežne znake brez težav lahko pišemo tudi tedaj, kadar ni treba '\"Grem v rudnik,\" je rekla.'. Z ubežnimi znaki lahko zapišemo tudi znak za novo vrstico \n, za tabulator \t in seveda tudi za poševnico \\, saj je ne moremo pisati le kot \, ker bi Python to razumel kot začetek ubežnega znaka.

Nize lahko pišemo tudi med tri enojne (''') ali tri dvojne (""") narekovaje (ki smo jih videli že pri dokumentacijskem nizu). V tem primeru za en sam narekovaj ne potrebujemo ubežnega znaka. Take nize lahko pišemo tudi čez več vrstic.

Različni zapisi ne vplivajo na vsebino. Tako '"Živjo!"', '\"Živjo!\"',"\"Živjo!\"", '''"Živjo!"''' ali """"Živjo!\"""" vsi predstavljajo enak niz z osmimi znaki.

Vgrajene metode na nizih#

Precej operacij na nizih pa lahko opravimo preko metod. To so funkcije, ki jih na poseben način kličemo na posamezni vrednosti. Na primer, za pretvarjanje niza v male črke pokličemo

'REKURZIJA'.lower()
'rekurzija'

Klic metod na nizih ima splošno obliko niz.metoda(...), kjer v oklepajih naštejemo argumente. Na primer, pojavitve posameznega znaka v nizu preštejemo z metodo count:

niz = 'Otorinolaringolog'
niz.count('o')
4

Klice metod lahko tudi verižimo:

niz = 'Otorinolaringolog'
niz.lower().count('o')
5

Vse metode, ki so na voljo na nizih lahko najdete v uradni dokumentaciji, zato naštejmo le najbolj pogosto uporabljane:

  • s.count(t) vrne število pojavitev podniza t v nizu s. Klic s.count(t, i) deluje podobno, le da začne šteti šele pri indeksu i, klic s.count(t, i, j) pa konča šteti pri indeksu j.

  • s.index(t) vrne najmanjši indeks v nizu s, kjer se niz t pojavi kot podniz. Podobno kot prej klic s.index(t, i) začne iskati pri indeksu i, klic s.index(t, i, j) pa konča pri indeksu j. Če niza ni, metoda sproži napako. Metoda s.find se obnaša enako kot s.index, le da v primeru, ko podniza ne najde, vrne -1.

  • s.join(sez) z ločilom s skupaj stakne vse nize iz seznama sez (te bomo spoznali kmalu).

  • s.replace(t1, t2) vrne niz s, v katerem smo vse pojavitve podniza t1 zamenjali s podnizi t2. Klic s.replace(t1, t2, n) pa zamenja le prvih n pojavitev.

  • s.strip() vrne niz s, v katerem smo odstranili vse bele znake (presledke, tabulatorje, nove vrstice) z začetka in konca. Klic s.strip(t) z začetka in konca odstrani vse znake iz niza t.

  • s.lower() / s.upper() / s.title() / s.capitalize() / s.swapcase() vrnejo niz s, v katerem smo vse črke zamenjali z malimi / vse črke zamenjamo z velikimi / vsem besedam damo veliko začetnico / na začetku niza damo veliko začetnico / male črke zamenjamo z velikimi in obratno.

  • s.split() vrne seznam besed v nizu s (ločene glede na bele znake). Klic s.split(t) loči glede na podniz t. Klic s.split(t, n) vrne niz razbit na prvih n ločilih.

  • s.isdigit() / s.isalpha() / s.islower() / s.isupper() / s.isalnum() / s.isspace() vrnejo True natanko takrat, kadar je niz s neprazen in so vsi znaki števke / črke / male črke / velike črke / črke ali številke / beli znaki.

f-nizi#

Včasih je bila v Pythonu zelo uporabna tudi metoda format. Ta vzame niz, v katerem so z zavitimi oklepaji označeni prostori, ki jih zapolnimo z argumenti metode. Na primer

'{0} ima {1}'.format('mama', 'stol')
'mama ima stol'

ali pa

niz = '{0} vzklika: "{1}, {1}, {1}!"'
niz.format('Mama', 'joj')
'Mama vzklika: "joj, joj, joj!"'
niz.format('Tone', 'FMF')
'Tone vzklika: "FMF, FMF, FMF!"'

Argumente lahko tudi oblikujemo in poimenujemo, kar je razloženo v uradni dokumentaciji. Po novem, od Pythona 3.6 naprej, pa lahko uporabljamo tudi f-nize. To so nizi, ki jih na začetku označimo z znakom f, nato pa v zavite oklepaje zapišemo vrednost, ki naj jo Python izračuna in vstavi v niz. Na primer:

kdo = 'Mama'
kaj = 'joj'
f'{kdo} vzklika: "{kaj}, {kaj}, {kaj}!"'
'Mama vzklika: "joj, joj, joj!"'

ali pa

a, b = 22, 7
f'{a}/{b} = {a / b:.5}'
'22/7 = 3.1429'

Tako kot pri metodi format lahko tudi pri f-nizih izračunane vrednosti oblikujemo:

a, b = 22, 7
f'{a}/{b} = {a / b:.5}'
'22/7 = 3.1429'
f'popust znaša {1 / 3:.2%}'
'popust znaša 33.33%'
f'{"NASLOV":*^30}'
'************NASLOV************'

Možnosti za oblikovanje je veliko, vse pa so opisane v uradni dokumentaciji.

Pisanje na konzolo in branje s konzole#

Seveda od uporabnikov ne pričakujemo, da bodo naše programe uporabljali le tako, da bodo v interaktivni zanki poganjali funkcije ter brali njihove rezultate. Raje bi imeli prijazen uporabniški vmesnik, v katerem računalnik uporabnika prijazno pozove za vnos, uporabnik potem nekaj natipka (ne nujno v Pythonu), računalnik pa se na to ustrezno odzove. V ta namen sta namenjeni dve funkciji print, ki dani niz izpiše na konzolo, ter input, ki vrne niz, ki ga je vtipkal uporabnik.

print('Pozdravljen, svet!')
Pozdravljen, svet!
print('"Tole je kr\'neki," je rekla.')
"Tole je kr'neki," je rekla.

Kot vidimo, je izpis funkcije print namenjen uporabnikom.