Nizi - uporaba funkcij in metod

Nizi - uporaba funkcij in metod

Avtor: Svetlana Novak

Učni cilji: Dijak se nauči uporabljati funkcije in metode za delo z nizi v programskem jeziku Python.

Nizi - uvod

Potrebno predznanje:

  • kaj so nizi in kako jih zapisujemo (uporaba narekovajev)
  • seznami in metode za delo s seznami
  • branje nizov: uporaba funkcije input()
  • dolžina niza: funkcija len()
  • indeksiranje znakov v nizu
  • primerjava nizov
  • funkcije: ustvarjanje novih in klicanje

Nizi - rezanje (slicing)

Zakaj rezanje: spreminjanje posameznega znaka v nizu ni dovoljeno

Pri nizih ne moremo spreminjati znakov na posameznem indeksu (položaju v nizu), ker nizi niso seznami. Podobnost nizov s seznami pa se kaže ravno pri operacijah rezanja (slicing) in tudi indeksiranje (določanje položaja znaka v nizu) se pri nizih začne z indeksom 0.

Nizi so nespremenljivi, kar pomeni, da spodnji primer ni dovoljen:

niz = 'andrej'
niz[0]= 'A'    # prevajalnik javi napako


(Slice.JPG)
Slika 1: Napaka




Spreminjanje nizov z rezanjem

Lahko pa niz spreminjamo na drug način - z rezanjem in sestavljanjem v novi niz, kar kažejo spodnji primeri v kodi:

niz = 'andrej'
niz = 'A' + niz[1:] + 'a'      # v niz je 'Andreja'
niz1 = niz[:-4]                # v niz1 je 'And' (izpusti zadnje 4 znake)
niz2 = niz[:3] + 'i'           # v niz2 je 'Andi'
niz3 = niz[2:4]                # v niz3 je 'dr'
niz4 = niz[:4] + niz[-1]       # v niz4 je 'Andra'
niz5 = niz[::2]                # v niz5 je 'Adea'

Nizi so sicer besedila sestavljena iz znakov, ki so v programu napisani med enojnimi ali dvojnimi narekovaji, tako da zgornjo kodo lahko napišemo tudi kot:

niz = "andrej"
niz = "A" + niz[1:] + "a"      # v niz je 'Andreja'

Nikakor pa v zapisu niza (v programski kodi) ne smemo mešati narekovajev: začeti z enojnim in končati z dvojnim ali obratno. Priporoča se uporaba enega tipa oklepajev.

Če pokomentiramo zgornje primere:

  •  niz[1:]  podniz se začne z drugim znakom, ki je na indeksu 1 in konča na koncu niza oz. odstrani prvi znak v nizu,
  •  'A' + niz[1:] + 'a'  na začetku je velika črka A, iz niza niz se odstrani prvi znak in ta podniz doda k veliki črki A in na koncu se doda še malo črko a - dobimo novi niz 'Andreja',
  •  niz[:3]  podniz je sestavljen iz prvih treh znakov v nizu niz. Zapis pomeni, da se podniz začne pri 0-tem indeksu, znak z indeksom 3 pa ni več zraven (zadnji je znak na indeksu 2),
  •  niz[::2]  pri rezanju lahko določamo tudi korak, ki pove, kateri po vrsti znaki bodo v podnizu. Ker je začetni in končni indeks izpuščen, začnemo z 0-tim, končamo z zadnjim, v tem primeru pa je izpuščen vsak drugi znak, ki je sicer v nizu niz na lihem indeksu.

Drugače so oznake indeksov pri rezanju:

niz[začetni_indeks:končni_indeks:korak]

  • kjer je začetni_indeks indeks prvega znaka. Če ni vrednosti, pomeni indeks 0,
  • končni_indeks je indeks prvega znaka, ki ga ni v podnizu. Če ni vrednosti, pomeni zadnji znak,
  • korak pomeni, da je indeks vsakega naslednjega znaka, ki je v podnizu, za korak indeksov odmaknjen od prejšnjega znaka.

Obračanje niza

Rezanje lahko uporabljamo tudi za obračanje nizov.

>>> beseda = "Ni konj"
>>> obrnjenaBeseda = beseda[::-1]
>>> obrnjenaBeseda
'jnok iN'
>>> beseda
'Ni konj'

Pri obračanju z rezanjem je korak (glejte opis oznake indeksov pri rezanju) negativen, začetni in končni indeks pa pomenita enako, le da je pri obračanju začetni indeks rezanja končni indeks niza, končni pa zadnji znak, ki ga nočemo več imeti v nizu (ZATO: končni ne sme biti 0, če hočemo imeti v obrnjenem nizu vse znake).

Nizi - rezanje: razlika med nizi in seznami

Če so nizi nespremenljivi, kako lahko sestavljamo nize (dodajamo nove nize k obstoječim)? Kadar nespremenljiv razred podpira operator sestavljanja, to stori tako, da vrne nov objekt.


>>> l = k = [1, 2]
>>> k = k + [3]
>>> l
[1, 2, 3]
>>> k
[1, 2, 3]
>>>
>>> a = b = "Ana"
>>> b = b + "Marija"
>>> a
'Ana'
>>> b
'AnaMarija'

Do razlike pride, ker je seznam spremenljiv, zato k = k + [3] pripne nov seznam k obstoječemu seznamu. Čeprav smo [3] pripeli h k, se je spremenil tudi l, ker gre še vedno za en in isti objekt. Z nizi pa je drugače. Niza b ni mogoče spreminjati, zato prištevanje naredi nov niz, a pa še vedno obdrži staro vrednost.



Nizi - rezanje: zgled

Uporaba:

Naloga: Napišite ukaze, pri katerih na začetku vpišete niz, ki predstavlja EMŠO, in nam izpiše datum, mesec in leto rojstva osebe.

Rešitev:

Prvi približek rešitve je trivialen. Prvi dve števki predstavljata dan, drugi dve mesec, tretje tri leto.


emso = input("Vpišite EMŠO osebe: \")
dan = emso[:2]             # režemo 1 in drugi znak
mesec = emso[2:4]          # režemo tretji in četrti znak
leto = ("2" if emso[4]=="0" else "1") + emso[4:7]
                           # uporabimo pogojni izraz, ki doda pred letnico "2", če je peti znak "0",
                           # sicer doda "1", režemo pa od petega do sedmega znaka

Primer 1 (EMŠO številke so izmišljene in brez preverjanja veljavnosti 13. mesta v številki, ki je sicer kontrolna številka):

>>> emso = '0101999500113'
>>> dan = emso[:2]
>>> mesec = emso[2:4]
>>> leto = ("2" if emso[4]=="0" else "1") + emso[4:7]
>>> print(dan, mesec, leto)
01 01 1999

Primer 2:

>>> emso = '0712009505222'
>>> dan = emso[:2]
>>> mesec = emso[2:4]
>>> leto = ("2" if emso[4]=="0" else "1") + emso[4:7]
>>> print(dan, mesec, leto)
07 12 2009

Nizi - list

Funkcija list naredi seznam iz niza znakov oz. niz pretvori v tip seznam. Elementi seznama so posamezni znaki iz niza. Nizom vrednosti ni dovoljeno spreminjati na način, na kateri spreminjamo vrednosti elementov seznama: elementu z indeksom priredimo novo vrednost. Pri nizih tako uporabimo rezanje, ki lahko sledi funkciji list nad nizi ali pa režemo brez uporabe list.

Uporaba funkcije list

Nizi - list: zgledi

Uporaba funkcije 1:

Koda:

beseda = 'Ni konj'
seznam = list(beseda)

V seznamu seznam dobimo elemente:

['N', 'i', ' ', 'k', 'o', 'n', 'j']

Uporaba funkcije 2: S pomočjo funkcije sorted() uredi znake v nizu. Pred urejanjem uporabi pretvorbo niza v seznam znakov s funkcijo list(). Leksikografsko so velike črke pred majhnimi, zato je na spodnjem primeru (glej sliko 2) črka N pred i, j, k, n in o.

Koda:

niz = 'Ni konj'
seznam = list(beseda)      # iz niza v seznam
seznam2 = sorted(seznam)   # znaki seznama urejeni leksikografsko in shranjeni v nov seznam


(List.JPG)
Slika 2: Koda reševanja

Nizi - metoda split

Metoda split razdeli niz na podnize, kakor jih ločuje podano ločilo. Privzeto ločilo je beli prostor (whitespaces: presledek, tabulator, ...). Podnizi so shranjeni v seznamu.


>>> "Ana Berta Cilka Dani".split()
['Ana', 'Berta', 'Cilka', 'Dani']

>>> "Ana - Berta - Cilka – Dani".split()
['Ana', '-', 'Berta', '-', 'Cilka', '-', 'Dani']

Ločilo je lahko tudi drugačno:

>>>'12/3/99'.split('/')
['12', '3', '99']

In tudi niz znakov:

>>> "Ana - Berta - Cilka - Dani".split(" - ")
['Ana', 'Berta', 'Cilka', 'Dani']

>>>"a+b-c".split("+-")
['a+b-c']

V prvem zgornjem primeru so ločilni znaki v nizu (' - ') in samo takšna kominacija v nizu ločuje v seznam podnizov. V drugem primeru pa metoda split() v nizu 'a+b-c' ni naletela na kombinacijo znakov '+-', tako da je v seznamu samo en element in to je prvotni niz.

V naslednjem primeru z metodo split() ustvarimo seznam nizov, v katerem je toliko podnizov, koliko je ločilnih znakov+1. V tem primeru je ločilnih znakov 6 (šest znakov '+'), zato je podnizov 7.

>>>'a++++++a'.split('+')
['a', '', '', '', '', '', 'a']

Poglejmo še razliko med split() in split(' '):

>>>'a      a'.split()
['a', 'a']

>>>'a      a'.split(' ')
['a', '', '', '', '', '', 'a']

Če v metodi split() ni parametrov, pomeni, da so ločilni znaki beli presledki (white spaces kot so presledek ' ', znak za novo vrsto '\n', tabulator), ki jih Python ignorira in na tistem mestu, kjer se pojavijo (eden ali več po vrsti), ustvari nov podniz za v seznam. V drugem primeru pa se za vsak presledek ustvari niz dolžine št. presledkov+1 v seznamu.

Uporaba split pri vnosu več spremenljivk:

vnos = input('Vnesi dve števili, ločeni s presledkom').split()
prvoStevilo = int(vnos[0])
drugoStevilo = int(vnos[1])

Nizi - metoda split: zgled

Naloga: Sestavi funkcijo, ki za parameter dobi niz, v katerem so z vejicami ločena cela števila. Funkcija naj vrne vsoto teh števil.


>>> vsota('5,124,52,-10,21')
192

Rešitev

Vsota števil v nizu

Izračunaj vsoto števil v nizu. Števila so ločena z vejicami.

Rešitev:

Najprej naredimo seznam, v katerem so podnizi, ki smo jih dobili z uporabo metode split nad nizom. Elementi seznama so nizi, ki jih z ustrezno funkcijo spremenimo v cela števila. Vsa števila med seboj seštejemo. Uporaba: v tekstovnih datotekah so vsa števila v tekstovni obliki in jih s spremembo iz nizov v števila obdelujemo naprej kot števila.


def vsota(niz):
   seznam = niz.split(',')
   vsota = 0            # vsoto na začetku na 0
   for st in seznam:    # gremo po vseh številih iz seznama
       vsota = vsota + int(st)

   return vsota

Zapri

Nizi - metoda join

Metoda join naredi ravno nasprotno: seznam nizov združi v en sam niz. Zasukana je nekoliko nenavadno: ločilu povemo, naj združi nize iz podanega seznama. Metoda lahko uporabljamo pri sestavljanju nizov. Primer: niz spremeni v seznam, seznam obrne in ga z metodo join spremeni nazaj v niz.

Primer ukaza join z uporabo ločila:

>>> seznam = ['Jože', 'Mojca', 'Janez', 'Miha', 'Matej']
>>> niz = ','.join(seznam)
>>> niz
'Jože,Mojca,Janez,Miha,Matej'

Primer obrnjenega niza:

>>>seznam = list(niz)
>>>seznam.reverse()
>>>obrnjeniNiz = ''.join(seznam)

Ali pa združevanje več nizov v seznamu v en niz z različnimi ločili:

>>> ' '.join(['Janez', 'Novak'])
'Janez Novak'
>>> '/'.join(['11', '11', '2011'])
'11/11/2011'
>>> '\n'.join(['prva vrstica', 'druga vrstica', 'tretja vrstica'])
'prva vrstica\ndruga vrstica\ntretja vrstica'
>>> 'cm x '.join(['15', '20', '7']) + 'cm'
'15cm x 20cm x 7cm'

V zgornjih primerih:

  • v prvem je ločilo presledek ' ',
  • v drugem '/',
  • v tretjem je ločilo znak za novo vrsto, ki pa ga da samo na konec prvega in drugega niza v seznamu,
  • v četrtem dodamo dimenzije in znak za krat ('x'), na konec pa še 'cm', ker se ločilni znaki dodajajo samo med nize v seznamu, ne pa tudi na konec k zadnjemu nizu.

Pa še primer, ki ne deluje:

>>>'cm x '.join([15, 20, 7]) + ' cm'
Traceback (most recent call last):
  File "<pyshell#60>", line 1, in <module>
    'cm x '.join([15, 20, 7]) + 'cm'
TypeError: sequence item 0: expected str instance, int found

V seznamu morajo biti nizi in ne števila. Števila pa pretvorimo v nize s funkcijo str(). Zapis s pretvorbo števil:

>>>'cm x '.join([str(15), str(20), str(7)]) + 'cm'

(ListJoin.JPG)
Slika 3: Koda list in join

Nizi: vprašanje 1

Poveži ukaz z rešitvijo.

"M:o:j:c:a".split(':')
':'.join(list("Mojca")[::-1])
list('Sandi')[1:4]
['M', 'o', 'j', 'c', 'a']
'a:c:j:o:M'
['a', 'n', 'd']
'acjoM'

Preveri

Pravilno

Dobro si začel/-a. Uspešno naprej.

Naprej

Napačno

Ni ti še uspelo. Preberi razlago in poskusi ponovno.

Zapri

Nizi: vprašanje 2

Izberi napačen odgovor.

Preveri

Pravilno

Dobro poznaš delo z nizi.

Naprej

Napačno

Mogoče še nekaj časa posvetiš teoriji? Poskusi še enkrat. Saj bo šlo.

Zapri

Nizi: vprašanje 3

V vrstici neke tekstovne datoteke, ki je niz, imamo zapisane dnevne temperature, merjene vsako polno uro v enem dnevu. Vrednosti so zapisane kot cela števila, ločene z vejicami. Tako imamo v vrstici zapisanih 24 podatkov. Katere funkcije in metode za delo z nizi bi uporabili za računanje povprečne temperature dneva?

Izberi pravilni odgovor.

split, int
join, split
int, list

Pravilno

Čestitam. Le tako naprej.

Naprej

Napačno

Malo je zmanjkalo. Ne obupaj. Poskusi še enkrat.

Zapri

Nizi: vprašanje 4

Imaš deklariran niz

 niz = "Moja domača naloga" 

Če narediš novi niz, ki je narejen iz prejšnjega po sledeči sintaksi

 nizNov = niz[2:7] 

koliko znakov vsebuje novi niz nizNov?

Odgovor

Preveri

Pravilno

Čestitam. Dobro ti gre.

Naprej

Napačno

Napačen odgovor. Namig: dolžina niza, ki ga dobimo z rezanjem, je zgornja minus spodnja vrednost v oglatih oklepajih. Poskusi ponovno.

Zapri

Nizi: vprašanje 5

Izberi tri (3) pravilne odgovore, ki določajo pravilne ukaze (funkcije oz. metode) za delo z nizi.

Preveri

Pravilno

Poiskal si vse pravilne odgovore. Odlično. Kviz je zate zaključen.

Naprej

Napačno

Odgovor ni popoln. Prosim, potrudi se še malo.

Zapri

Nizi: primer uporabe - temperature

Naloga: Izračunajte povprečno temperaturo, ki jo je v enem dnevu izmeril termometer merilne postaje Prešna Loka. Podatke dobimo v obliki niza. V nizu so podatki od enega dneva, merjeni pa so na desetinko stopinje Celzija natančno. Podatki so med seboj ločeni z znakom lojtra '#'. Po navadi je interval med dvema meritvama natančno določen, ker pa se lahko zgodi, da kakšna meritev izpade, povprečno temperaturo izračunamo iz obstoječih podatkov. Bodite pazljivi, da prikažete pravo temperaturo, ker so meritve v desetinkah.

Postopek reševanja Napišite funkcijo, ki izračuna povprečno temperaturo vseh meritev, ki so zapisane v nizu in ločene z znakom '#'. Meritve so v desetinkah stopinj Celzija. Iz niza so pred vhodom v funkcijo izločene vse nepravilnosti kot so lojtra na koncu niza in same lojtre v nizu.

Funkcija:

  1. Parameter funkcije je niz s podatki.
  2. Niz v funkciji s pomočjo metode split() shranite v seznam nizov, ki so temperature.
  3. Vsoto temperaturnih meritev postavimo na 0.
  4. V zanki se premikamo po vseh elementih seznama in nize pretvarjamo v decimalna števila ter jih seštejemo v vsoto.
  5. vsoto spremenimo v stopinj Celzija z deljenjem z 10 (ker so meritve v desetinkah)
  6. Vsoto nato še delimo s številom meritev, ki ga dobimo iz velikosti seznama temperatur, in rezultat shranimo v spremenljivko povp.
  7. Funkcija vrne povprečno temperaturo (vrednost povp).

    Rešitev:
(Povprecje.png)
Slika 4: Koda uporabe metode split()
0%
0%