Funkcijam, ki smo jih srečevali doslej, smo, da so kaj naredile, morali dati
podatke, na katerih so delale. Funkcija len
kot argument
zahteva seznam ali niz, katerega dolžino bi radi izvedeli. Funkcija
input
kot argument želi niz z vprašanjem, ki bi ga radi
zastavili uporabniku. Razen argumentov, ki jih podamo, te funkcije nimajo
drugih podatkov (vsaj ne, da bi mi vedeli zanje).
Ko smo se učili o seznamih, pa smo mimogrede naleteli na neko nenavadnost:
za dodajanje novega elementa v seznam nismo poklicali funkcije, ki bi ji
podali seznam in element (na primer append(imena, "Ana")
),
temveč smo morali napisati ime seznama, ki mu je sledila pika in
append
, kot argument pa smo navedli le element, ki smo ga
želeli dodati, torej imena.append("Ana")
.
>>> imena = [] >>> imena.append("Ana") >>> imena.append("Berta") >>> imena ['Ana', 'Berta']
append
je očitno nenavaden, ne kličemo ga tako kot druge
funkcije. Funkcija append
"pripada" seznamu; zato mu pravimo
imena.append
. Naredimo še en seznam.
>>> teze = [] >>> teze.append(55) >>> imena.append("Cene") >>> imena ['Andrej', 'Branka', 'Cene'] >>> teze [55]
Vsak seznam ima svoj append
: imena
imajo
imena.append
in teze
imajo
teze.append
.
Takšnim funkcijam pravimo metode. Klic imena.append
si predstavljamo, kot da seznamu imena
rečemo "dodaj si
element" "Cene"
in klic teze.append(55)
pomeni, da seznamu teze
rečemo "dodaj si element"
55
.
Pika, .
izraža nekakšno pripadnost, vsebovanost. Ko smo
spoznali module, smo videli, da z math.sqrt
pridemo do
"math"ove funkcije z imenom "sqrt". Z imena.append
zahtevamo
"imenovo" metodo "append". In z teze.append
"tezovo" metodo
"append".
Takšnih metod je še veliko: takole prosimo niz ime
, naj nam
pove, koliko črk "n" vsebuje.
>>> ime = "Benjamin" >>> ime.count("n") 2
Takole pa niz fname
vprašamo, ali se konča s "torrent":
>>> fname.endswith("torrent") True
Kako bi Benjamina spremenili v Benjamaxa? Težko: kot vemo, so nizi nespremenljivi (tako kot terke; od vsega, o čemer smo govorili prejšnji teden, lahko spreminjamo samo sezname). Pač pa lahko vprašamo niz, kako bi bil videti, če "min" zamenjano z "max".
>>> ime.replace("min", "max") 'Benjamax'
Metode niso povezane s tem, ali je niz shranjen v spremenljivki ali ne. Metodo moremo poklicati tudi na nizu "kar tako".
>>> "Maja".lower() 'maja'
So z metodami obdarjeni samo nizi? Je to edinstven primer objektov v Pythonu, ki imajo metode? Ne, nič ne bi moglo biti dalj od resnice! Skoraj vsaka reč v Pythonu ima metode (ali vsaj nekaj podobnega). Celo običajna števila imajo metode, čeprav zgolj tehnično in z zelo čudnimi imeni, kot lahko vedoželjen študent hitro preveri:
>>> (-231).__abs__() 231
Med tipi, ki smo jih spoznali doslej, pa imajo uporabe vredne metode nizi in seznami. V okviru predavanj ne bomo podrobneje spoznavali vse mogočih podatkovnih tipov. Temeljiteje pa bomo pogledali metode nizov, seznamov in podobnih reči, ki jih pri programiranju v Pythonu vsakodnevno uporabljamo. Obenem bomo tako dobili vtis, kako te reči izgledajo. Najprej nizi.
Nekaj smo jih že spoznali: count
, replace
in
lower
. Zadnja ima sestro, upper
, ki vrne niz,
pri katerem so vse črke pretvorjene v velike črke.
>>> "Maja".lower() 'maja' >>> "Maja".upper() 'MAJA'
V žlahti z njima sta še (ne posebej uporabna) capitalize
in
title
.
>>> "benjamin".capitalize() 'Benjamin' >>> "tole je stavek, ki ga bomo povelikocrkali po anglesko".title() 'Tole Je Stavek, Ki Ga Bomo Povelikocrkali Po Anglesko'
Da ne bi kdo pozabil, za vsak slučaj še enkrat spomnimo: te metode ne spreminjajo niza, temveč vračajo nove nize. Nizi ostanejo takšni, kot so bili. Po tem primeru bi moralo biti jasno, kaj ne deluje in kako je potrebno pisati, da bo delovalo.
>>> s = "benjamin" >>> s 'benjamin' >>> s.capitalize() 'Benjamin' >>> s 'benjamin' >>> s = s.capitalize() >>> s 'Benjamin'
Metodo count
smo že spoznali. Povejmo le še, da lahko išče
tudi daljše podnize, ne le posamezne znake.
>>> "Maja".count("a") 2 >>> "Maja".count("aj") 1
Poleg count
imamo tudi nekaj funkcij, ki povedo, kje v nizu
se nahaja določen podniz. Prvi sta find
in index
.
>>> s 'Benjamin' >>> s.find("jam") 3 >>> s.index("jam") 3
Edina razlika med njima je v tem, kaj storita, če iskanega niza ni.
find
vrne -1, index
pa javi napako.
>>> s.find("maj") -1 >>> s.index("maj") Traceback (most recent call last): File "", line 1, in ValueError: substring not found
Če se dani podniz pojavi večkrat, bosta funkciji vrnili indeks prve
pojavitve - razen, če jima z dodatnimi argumenti povemo, od kod naprej
naj iščeta. Poleg find
in index
obstajata še
funkciji rfind
in rindex
, ki iščeta s konca in
tako vrneta zadnjo pojavitev podniza v nizu.
Mimogrede smo že omenili tudi preprosto, a zelo uporabno funkcijo
endswith
, ki pove, ali se niz konča s podanim podnizom.
Poleg njega obstaja še startswith
, ki pove ali se niz
začne z danim podnizom.
Metode ljust
, rjust
in center
dopolnijo niz s presledki z leve, z desne ali z obeh strani, tako da je
dolg toliko, kot želimo. Takole napihnemo Benjamina na 15 znakov:
>>> s.ljust(15) 'Benjamin ' >>> s.rjust(15) ' Benjamin' >>> s.center(15) ' Benjamin '
(Še enkrat: te metode ne spreminjajo niza, temveč vrnejo nov niz!)
Metoda strip
naredi ravno nasprotno: odbije presledke (in
tabulatorje in znake za prehod v novo vrstico) na levi in desni strani
niza. lstrip
in rstrip
pospravita samo levo in
samo desno stran.
>>> s = ' asdf ' >>> s.lstrip() 'asdf ' >>> s.rstrip() ' asdf' >>> s.strip() 'asdf'
Če se zdi ta metoda komu neuporabna, se moti. Zelo.
Nizi imajo še veliko metod. Pogledali bomo le še dve najzanimivejši.
Metoda split
razbije niz na seznam podnizov, kakor jih ločujejo
presledki, tabulatorji in znaki za nove vrstice. (V prvem približku:
razbije jih na besede.)
>>> s = 'Metoda split razbije niz na seznam podnizov, kakor jih ločujejo presledki.' >>> s.split() ['Metoda', 'split', 'razbije', 'niz', 'na', 'seznam', 'podnizov,', 'kakor', 'jih', 'locujejo', 'presledki.']
Presledkom, tabulatorjem in znakom za novo vrstico rečemo tudi beli
prostor (white space). Namesto glede na beli prostor lahko
split
razbije niz tudi glede na kak drug znak, ki ga moramo
v tem primeru podati kot argument.
>>> "123-4123-21".split("-") ['123', '4123', '21'] >>> "123-4123-21".split("1") ['', '23-4', '23-2', '']
Zadnja metoda, join
, dela ravno obratno kot split
:
združuje nize. Način, na katerega je obrnjena, je nenavaden, a če malo
razmislimo, vidimo, da drugače ne bi moglo biti.
>>> imena = ["Ana", "Berta", "Cilka", "Dani", "Ema"] >>> "".join(imena) 'AnaBertaCilkaDaniEma'
Praznemu nizu, "", smo "naročili", naj združi nize iz podanega seznama. To sicer ni videti preveč lepo, lepše bo, če jih združimo s kakim ločilom.
>>> "-".join(imena) 'Ana-Berta-Cilka-Dani-Ema' >>> ", ".join(imena) 'Ana, Berta, Cilka, Dani, Ema' >>> "--".join(imena) 'Ana--Berta--Cilka--Dani--Ema' >>> " in ".join(imena) 'Ana in Berta in Cilka in Dani in Ema'
Najlepše pa bo, če zadnjo vejico zamenjamo z "in".
>>> ", ".join(imena[:-1]) + " in " + imena[-1] 'Ana, Berta, Cilka, Dani in Ema'
Tule smo z join
združili vse elemente razen zadnjega. K temu
nizu smo prišteli niz " in " in še zadnje ime s seznama.
Tako kot nizi imajo tudi seznami metodi count
in
index
, o katerih ne bomo izgubljali besed.
Omenili smo že append
, ki v seznam doda nov element. Pazite,
tole je pa zelo drugače kot pri nizih! Metoda append
ne vrača
novega seznama, temveč v resnici spreminja seznam.
Kako pa bi k nizu pripeli seznam? Tule nam append
ne bo
pomagal: kar naredi, je povsem narobe.
>>> imena ['Ana', 'Berta', 'Cilka', 'Dani', 'Ema', 'Fanci', ['Greta', 'Hilda']]
Kaj smo pa pričakovali? Metoda append
doda k seznamu nov
element. Kar ji podamo kot argument, bo zadnji element seznama. Če torej
append
u podamo seznam, bo seznam zadnji element seznama.
Uporabiti moramo metodo extend
.
>>> imena = ['Ana', 'Berta', 'Cilka', 'Dani', 'Ema', 'Fanci'] >>> imena.extend(["Greta", "Hilda"]) >>> imena ['Ana', 'Berta', 'Cilka', 'Dani', 'Ema', 'Fanci', 'Greta', 'Hilda']
Mimogrede, isto bi dosegli tudi z
imena += ["Greta", "Hilda"]
Metode extend
praktično ne uporabljamo, ker je nepotrebna.
Metodi insert
podamo dva argumenta, indeks in element, pa bo
vstavila element pred element s podanim indeksom (to si zapomnimo
takole: argument, ki ga podamo, bo indeks novega elementa).
>>> imena = ['Ana', 'Berta', 'Cilka', 'Dani', 'Ema', 'Fanci'] >>> imena.insert(2, "PredCilka") >>> imena.insert(-2, "PreEma") >>> imena ['Ana', 'Berta', 'PredCilka', 'Cilka', 'Dani', 'PreEma', 'Ema', 'Fanci']
Očitno deluje tudi indeksiranje s konca.
Elemente seznama lahko odstranjujemo na tri načine. Prvega smo spoznali že
prejšnjič: z ukazom del
. Še enkrat: del
ni metoda
in prihaja iz povsem drugega vica, a vseeno ga pač omenimo, ker sodi
sem.
>>> imena ['Ana', 'Berta', 'PredCilka', 'Cilka', 'Dani', 'PreEma', 'Ema', 'Fanci'] >>> del imena[2] >>> imena ['Ana', 'Berta', 'Cilka', 'Dani', 'PreEma', 'Ema', 'Fanci']
Metoda pop
vrne element s podanim indeksom in ga pobriše s
seznama.
>>> ime = imena.pop(2) >>> ime 'Cilka' >>> imena ['Ana', 'Berta', 'Dani', 'PreEma', 'Ema', 'Fanci']
Priznati moram, da metode pop
nisem še nikoli uporabil na ta
način - vsaj ne da bi se tega spomnil. V resnici namreč vedno pobiramo
elemente z začetka ali s konca seznama. Metodo pop
lahko zato
pokličemo tudi brez argumentov: v tem primeru vrača zadnji element.
>>> imena ['Ana', 'Berta', 'Dani', 'PreEma', 'Ema', 'Fanci'] >>> imena.pop() 'Fanci' >>> imena.pop(0) 'Ana' >>> imena ['Berta', 'Dani', 'PreEma', 'Ema']
Če bi hoteli, recimo, prestaviti prvi element na konec, bi napisali
imena.append(imena.pop(0))
.
Tretji način je, da elementa, ki ga želimo odstraniti, ne določimo z
indeksom, temveč z vrednostjo - povemo, kakšen element bi radi odstranili.
Temu je namenjena metoda remove
.
>>> imena.remove("Dani") >>> imena ['Berta', 'PreEma', 'Ema']
Pri tem ne odstrani vseh takšnih elementov, temveč le prvega, na katerega naleti, kakor lahko vidimo v spodnjem primeru.
>>> s = [7, 1, 2, 3, 4, 1, 1, 2] >>> s.remove(1) >>> s [7, 2, 3, 4, 1, 1, 2]
Metoda s.copy()
naredi kopijo seznama s
, tako
kot da bi napisali s = s[:]
.
Metoda s.clear()
ga
izprazni, kar je isto kot s[:] = []
in ni isto kot
s = []
. Razlika je tako prefinjena, da bo vredna posebnega
predavanja.
Le še dve metodi sta nam ostali. reverse
obrne vrstni red
elementov v seznamu.
[7, 2, 3, 4, 1, 1, 2] >>> s.reverse() >>> s [2, 1, 1, 4, 3, 2, 7]
Zadnja je sort
, ki uredi elemente po vrsti.
>>> s.sort() >>> s [1, 1, 2, 2, 3, 4, 7]
Metoda deluje nad vsakršnimi elementi, ki jih je mogoče primerjati - z njo lahko uredimo seznam števil, nizov... Podamo ji lahko tudi kup argumentov, ki pa jih v tem trenutku še nismo zmožni razumeti.
Ne spreglejte razlike med metodami nizov in seznamov. Metode nizov vračajo
nove nize; s.replace("min", "max")
ni spremenil niza
s
, temveč vrnil nov niz. Metode seznamov spreminjajo seznam;
s.insert(2, "Ana")
ne vrne novega seznama, temveč spremeni
s
.
Terke imajo enake metode kot seznami, manjkajo jim le metode, ki spreminjajo
seznam. Teh pa, roko na srce, ni veliko. ;) Terke imajo le dve metodi:
count
in index
.