From 236001ec7563804f87a40c924681461bc8b2d764 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Mo=C5=BEina?= Poglejmo še enkrat sezname. Seznam je nekakšna zbirka nekih poljubnih
+ reči, pri čemer je vsaka reč v svojem "predalčku", predalčki pa so
+ oštevilčeni. Prvi ima številko 0, drugi 1, tretji 2 in tako naprej. Za
+ vsak predalček lahko pogledamo, kaj je v njem, spremenimo njegovo vsebino,
+ predalčke lahko odvzemamo in dodajamo.
+
+ Slovar (angl. dictionary, podatkovni tip pa se imenuje
+ Seznam in slovar se že od daleč (če niste kratkovidni) razlikujeta po
+ oglatosti. Seznam smo opisali tako, da smo v oglatih oklepajih
+ našteli njihove elemente. Slovar opišemo tako, da v zavitih
+ oklepajih naštejemo pare ključ: vrednost.
+
+ Stalno omenjani Benjamin si lahko takole sestavi slovar s telefonskimi
+ številkami svojih oboževalk:
+ Do vrednosti, shranjenih v slovarju, pride podobno kot do vrednosti v
+ seznamu: z indeksiranjem, le da v oglate oklepaje ne napiše zaporedne
+ številke, temveč ključ. Slovarji ne poznajo vrstnega reda. V slovarju ni prvega, drugega, tretjega
+ elementa. Ne le zato, ker oznake niso številke. Ne, slovar si v resnici ne
+ zapomni vrstnega reda, v katerem smo našteli elemente, niti ne vrstnega
+ reda, v katerem jih dodajamo. (Čemu?! Čemu je to potrebno? Čemu zmeša vrstni red?! Mar ne more zlagati
+ teh reči lepo po vrsti? Izvedeli boste drugo leto. V resnici ni zmešan,
+ temveč prav premeteno premetan. V tem, drugače preurejenem seznamu lahko išče
+ veliko hitreje.) Ker ni vrstnega reda, tudi ni rezin. Tole sporočilo o napaki je sicer zelo čudno, vendar povsem smiselno. Boste
+razumeli, ko boste veliki. ;) O "mehaniki" slovarjev morate vedeti le tole: slovarji so hitri, saj
+ elementov v resnici ne iščejo. Na nek za zdaj skrivnosten način "vedo", kje
+ je vrednost, ki pripada danemu ključu. Ne da bi iskali, vedo, kam morajo
+ pogledati. Tudi dodajanje novih elementov v slovar je zelo hitro, enako tudi
+ brisanje. Cena, ki jo plačamo za to, je dvojna. Ključi so lahko le
+ podatkovni tipi, ki so nespremenljivi. Nespremenljivi podatkovni tipi so,
+ vemo, nizi, števila, logične vrednosti in terke. Zgoraj smo kot ključ
+ uporabili niz. To je OK. Če bi poskušali kot ključ uporabiti seznam, ne bi
+ šlo. (V resnici je stvar malenkost bolj zapletena, ključ je lahko vsak
+ podatkovni tip, ki je "razpršljiv", vendar to ni za bruce). Omejitve
+ veljajo le za ključe. Vrednost je lahko karkoli. Drugi obrok cene, ki jo plačamo za učinkovitost slovarjev, je poraba
+ pomnilnika: slovar porabi nekako dvakrat več pomnilnika kot seznam. Koliko,
+ točno, več, je odvisno od velikost slovarja in tega, kaj shranjujemo.
+ Pri tem predmetu se s pomnilnikom ne obremenjujte. Aha, še tretji obrok cene, iz drobnega tiska: vsak ključ se lahko pojavi
+ največ enkrat. Če poskušamo prirediti neko vrednost ključu, ki že obstaja, le
+ povozimo staro vrednost. Ampak to je tako ali tako pričakovati. Tudi v
+ seznamu nimamo nikoli dveh različnih elementov na istem mestu. Lahko jim dodajamo nove elemente: preprosto priredimo jim nov element. Vprašamo se lahko, ali v seznamu obstaja določen ključ. Če se Cilka skrega z Benjaminom, jo lahko le-ta pobriše (mislim, pobriše
+ njeno številko). Če gremo prek slovarjev z zanko Slovar
+
+>>> s = [6, 9, 4, 1]
+>>> s[1]
+9
+>>> s.append(7)
+>>> s
+[6, 9, 4, 1, 7]
+>>> del s[3]
+>>> s
+[6, 9, 4, 7]
+>>> s[-2:]
+[4, 7]
+
+dict
) je podoben seznamu, le da se na predalčke sklicujemo z
+ njihovimi ključi (angl. key, ki so lahko števila, lahko
+ pa tudi nizi, logične vrednosti, terke... Temu, kar je shranjeno v predalčku
+ bomo rekli vrednost (value). stevilke = {"Ana": "041 310239", "Berta": "040 318319", "Cilka": "041 103194", "Dani": "040 193831",
+ "Eva": "051 123123", "Fanči": "040 135367", "Helga": "+49 175 4728 475"}
+
+>>> stevilke["Ana"]
+'041 310239'
+>>> stevilke["Dani"]
+'040 193831'
+
+>>> stevilke
+{'Dani': '040 193831', 'Fanči': '040 135367', 'Helga': '+49 175 4728 475',
+'Eva': '051 123123', 'Cilka': '041 103194', 'Berta': '040 318319',
+'Ana': '041 310239'}
+
+>>> stevilke["Ana":"Cilka"]
+Traceback (most recent call last):
+ File "
+
+Kaj lahko počnemo s slovarji?
+
+>>> stevilke["Iva"] = "040 222333"
+>>> stevilke
+{'Dani': '040 193831', 'Fanči': '040 135367', 'Iva': '040 222333',
+'Helga': '+49 175 4728 475', 'Eva': '051 123123', 'Cilka': '041 103194',
+'Berta': '040 318319', 'Ana': '041 310239'}
+
+append
ne obstaja, saj nima smisla: ker ni vrstnega reda, ne
+moremo dodajati na konec. Prav tako (ali pa še bolj) ne obstaja
+insert
, saj prav tako (ali pa še bolj) nima smisla.
+
+>>> "Cilka" in stevilke
+True
+>>> "Jana" in stevilke
+False
+
+>>> del stevilke["Cilka"]
+>>> stevilke
+{'Dani': '040 193831', 'Fanči': '040 135367', 'Iva': '040 222333',
+'Helga': '+49 175 4728 475', 'Eva': '051 123123',
+'Berta': '040 318319', 'Ana': '041 310239'}
+>>> "Cilka" in stevilke
+False
+
+for
, dobimo vrednosti
+ ključev.>>> for ime in stevilke:
+... print(ime)
+...
+Dani
+Fanči
+Iva
+Helga
+Eva
+Berta
+Ana
>>> for ime in stevilke: +... print(ime + ":", stevilke[ime]) +... +Dani: 040 193831 +Fanči: 040 135367 +Iva: 040 222333 +Helga: +49 175 4728 475 +Eva: 051 123123 +Cilka: 041 103194 +Berta: 040 318319 +Ana: 041 310239+ +
Vendar to ni najbolj praktično. Pomagamo si lahko s tremi metodami slovarja,
+ ki vrnejo vse ključe, vse vrednosti in vse pare ključ-vrednost. Imenujejo
+ se (ne preveč presenetljivo) keys()
, values()
in
+ items()
. Delamo se lahko, da vračajo sezname ključev,
+ vrednosti oziroma parov ... čeprav v resnici vračajo le nekaj, prek česar
+ lahko gremo z zanko for
.
+
+
Najprej poglejmo items()
.
>>> for t in stevilke.items(): +... ime, stevilka = t +... print(ime + ":", stevilka)+ +
Tole zgoraj je bilo seveda grdo. Lepo se reče takole:
+ +>>> for ime, stevilka in stevilke.items(): +... print(ime + ":", stevilke)+ +
Tako kot sem ob zanki for težil, da ne uporabljajte
+for i in range(len(s))
temveč for e in s
in da
+že v glavi zanke razpakirajte terko, kadar je to potrebno, bom težil tudi
+tule: uporabljajte items
in vaši programi bodo preglednejši in
+s tem pravilnejši.
Metoda values
vrne vse vrednosti, ki so v slovarju. V našem
+ primeru torej telefonske številke. Metodo values
človek včasih
+potrebuje, prav pogosto pa ne.
V nasprotju s tem metodo keys
potrebujejo samo študenti. Ne vem
+točno, zakaj sploh obstaja. No, vem, zato da študenti lahko pišejo
+for ime in stevilke.keys()
namesto
+for ime in stevilke
. Druge uporabne vrednosti pa ne vidim. :)
Skratka: ne uporabljajte metode keys
.
Slovar ima še dve metodi, ki smo ju videli tudi pri seznamu: metodo, ki + sprazni slovar in drugo, ki naredi nov, enak slovar.
+ +>>> stevilke2 = stevilke.copy() +>>> stevilke2 +{'Dani': '040 193831', 'Fanči': '040 135367', 'Iva': '040 222333', +'Helga': '+49 175 4728 475', 'Eva': '051 123123', +'Berta': '040 318319', 'Ana': '041 310239'} +>>> stevilke.clear() +>>> stevilke +{} +>>> stevilke2 +{'Dani': '040 193831', 'Fanči': '040 135367', 'Iva': '040 222333', +'Helga': '+49 175 4728 475', 'Eva': '051 123123', +'Berta': '040 318319', 'Ana': '041 310239'}+ +
Omenimo le še eno od slovarjevih metod, get
. Ta dela podobno
+ kot indeksiranje, stevilke.get("Ana")
naredi isto kot
+ stevilke["Ana"]
. Metodo get
uporabimo, kadar ni
+ nujno, da je ključ v seznamu in želimo v tem primeru dobiti neko privzeto
+ vrednost. Privzeto vrednost podamo kot drugi argument.
>>> stevilke.get("Ema", "ni številke") +'040 584928' +>>> stevilke.get("Greta", "ni številke") +'nimam stevilke'+ +
Še enkrat: ne pišite stevilke.get("Ema")
. To je čudno.
+Piše se stevilke["Ema"]
. Metodo get
uporabite le
+takrat, kadar niste prepričani, da slovar vsebuje ta ključ.
Neka naloga je šla takole.
+ +Veliko latinskih napisov, ki obeležujejo kak pomemben dogodek, je napisanih + v obliki kronograma: + če seštejemo vrednosti črk, ki predstavljajo tudi rimske številke (I=1, V=5, + X=10, L=50, C=100, D=500, M=1000), dajo letnico dogodka.
+ +Tako, recimo, napis na cerkvi sv. Jakoba v Opatiji, CVIVS IN HOC RENOVATA + LOCO PIA FVLGET IMAGO SIS CVSTOS POPVLI SANCTE IACOBE TVI, da vsoto 1793, + ko je bila cerkev prenovljena (o čemer govori napis).
+ +Pri tem obravnavamo vsak znak posebej: v besedil EXCELSIS bi prebrali + X + C + L + I = 10 + 100 + 50 + 1 = 161 in ne + XC + L + I = 90 + 50 + 1 = 141.
+ +Napiši program, ki izračuna letnico za podani niz.
+ +Očitna rešitev je:
+ +def kronogram(s): + v = 0 + for c in s: + if c=="I": + v += 1 + elif c=="V": + v += 5 + elif c=="X": + v += 10 + elif c=="L": + v += 50 + elif c=="C": + v += 100 + elif c=="D": + v += 500 + elif c=="M": + v += 1000 + return v+ +
Pri njej vsi, ki poznajo stavek switch
oz. case
+postokajo, kako je možno, da Python tega stavka nima. (Pustimo ob strani,
+ali je tole res toliko daljše od switch
, sploh če program nespodobno
+nabijemo skupaj:
def kronogram(s): + v = 0 + for c in s: + if c=="I": v += 1 + elif c=="V": v += 5 + elif c=="X": v += 10 + elif c=="L": v += 50 + elif c=="C": v += 100 + elif c=="D": v += 500 + elif c=="M": v += 1000 + return v+
). Ne, nima ga, ker ga skoraj nikoli ne potrebujemo. Tisto, kar delamo z +njim, pogosto rešimo (tudi) s slovarji.
+ +V slovar si bomo zapisali, katero številko pomeni katera črka.
+ +stevke = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}+ +
Funkcija zdaj deluje tako, da gre prek niza in za vsako črko preveri, ali je v +slovarju. Če je ni, ne pomeni številke; če je, prištejemo toliko, kolikor je +vredna.
+ +def kronogram(s): + v = 0 + for c in s: + if c in stevke: + v += stevke[c] + return v+ +
Še hitreje gre z get
; če črke ni, je njena privzeta vrednost 0.
+
def kronogram(s): + v = 0 + for c in s: + v += stevke.get(c, 0) + return v+ +
Ob tem si ne moremo kaj, da ne bi poškilili za en mesec naprej, ko se bomo + učili funkcijskega programiranja in znali biti še krajši in jedrnatejši, + spet predvsem po zaslugi slovarjev.
+ +def kronogram(s): + return sum(stevke.get(c, 0) for c in s)+ + +
Slovarji so uporabne reči. V veliko primerih pa uporabimo neko različico +slovarja, ki ima še eno dodatno sposobnost.
+ +Denimo, da smo dobili v preskušanje igralno kocko, za katero nas zanima, ali + goljufa. Stokrat smo jo vrgli in zabeležili rezultate.
+ +meti = [4, 4, 4, 3, 2, 3, 5, 3, 3, 4, 6, 6, 6, 1, 3, + 6, 6, 4, 1, 4, 6, 1, 4, 4, 4, 6, 4, 6, 5, 5, 6, 6, 2, 4, 4, 6, + 3, 2, 6, 1, 3, 6, 3, 2, 6, 6, 4, 6, 4, 2, 4, 4, 1, 1, 6, 2, 6, + 6, 4, 3, 4, 2, 6, 5, 6, 3, 2, 5, 1, 5, 3, 6, 4, 6, 2, 2, 4, 1, + 4, 4, 3, 1, 4, 2, 1, 3, 1, 4, 6, 1, 1, 3, 4, 1, 4, 3, 2, 4, 6, 6]+ +
Zanima nas, kolikokrat je padla katera številka. Nič lažjega. Najprej si + pripravimo seznam s sedmimi ničlami.
+ +>>> kolikokrat = [0] * 7 +>>> kolikokrat +[0, 0, 0, 0, 0, 0, 0]+ +
Zdaj nam bo, recimo kolikokrat[3]
povedal, kolikokrat je padla
+ trojka. (Čemu sedem? Saj ima kocka samo šest ploskev. Boste videli. Finta.)
+ Zdaj pa štejmo: pojdimo čez vse mete in povečujmo števce.
>>> for met in meti: +... kolikokrat[met] += 1 +... +>>> kolikokrat +[0, 14, 12, 15, 27, 6, 26]+ +
(Kje je finta? kolikokrat[0]
bo pove, kolikokrat je padla ničla.
+Nikoli pač. Napišite isto reč s seznamom dolžine šest, ne sedem. Ni problem,
+ampak tako, kot smo nardili je preprostejše.)
(Kocka je res videti nekoliko sumljiva: štirke in šestice so nekam pogoste + na račun petk. A pustimo statistikom vprašanje, ali je to še lahko + naključno ali ne.)
+ +Ups, nalogo smo rešili kar s seznamom! Da, to gre, ker so "predalčki" + seznama oštevilčeni, tako kot ploskve kocke. Tole pa ne bo šlo: tule je + seznam telefonskih številk deklet, ki jih je danes klical Benjamin. Katero + je poklical kolikokrat?
+ +klici = ['041 103194', '040 193831', '040 318319', '040 193831', '041 310239', + '040 318319', '040 318319', '040 318319', '040 193831', '040 193831', + '040 193831', '040 193831', '040 193831', '040 318319', '040 318319', + '040 318319', '040 193831', '040 318319', '041 103194', '041 103194', + '041 310239', '040 193831', '041 103194', '041 310239', '041 310239', + '040 193831', '041 310239', '041 103194', '040 193831', '040 318319']+ +
Za tako velike številke bi moral imeti seznam zelo veliko predalčkov. Še + huje bi bilo, če bi namesto seznama številk dobili seznam klicanih oseb.
+ +klici = ['Cilka', 'Dani', 'Berta', 'Dani', 'Ana', 'Berta', 'Berta', + 'Berta', 'Dani', 'Dani', 'Dani', 'Dani', 'Dani', 'Berta', 'Berta', + 'Berta', 'Dani', 'Berta', 'Cilka', 'Cilka', 'Ana', 'Dani', 'Cilka', + 'Ana', 'Ana', 'Dani', 'Ana', 'Cilka', 'Dani', 'Berta']+ +
Tu smo s seznamom pogoreli. No, ne čisto; rešitev s seznami seveda obstaja, + je pa zoprna - podobna je tistemu, kar smo v začetku počeli z bančnimi + računi.
+ +S slovarji je veliko lepše: +
pogostosti = {} +for ime in klici: + if ime not in pogostosti: + pogostosti[ime] = 0 + pogostosti[ime] += 1 +print(pogostosti)+ +
Ob vsakem novem klicu preverimo, ali je klicano ime
že v
+ slovarju. Če ga ni, da dodamo. Nato - najsibo ime novo ali ne - povečamo
+ števec klicev pri tej osebi.
Ker je ta stvar resnično pogosta, nam Python pomaga z modulom
+collections
, ki vsebuje podatkovni tip defaultdict
.
+(Modul, ki vsebuje podatkovni tip?! Da, da; tudi to je ena od stvari, ki jih
+bomo našli v modulih.) Ta se obnaša tako kot slovar, z eno izjemo: če zahtevamo
+kak element, ki ne obstaja, si ga meni nič tebi nič izmisli. Točneje, doda ga v
+slovar in mu postavi privzeto vrednost. Katero, določimo. Pri tem ne podamo
+privzete vrednosti, temveč "funkcijo", ki bo vračala privzeto vrednost.
+defaultdict
bo ustvarjal te, nove vrednosti tako, da bo poklical
+to funkcijo brez argumentov in kot privzeto vrednost uporabil, kar vrne
+funkcija, ki jo v ta namen vsakič sproti pokliče.
Zelo pogosto bo privzeta vrednost 0 in funkcija, ki vrača
+ 0, se imenuje, hm, int
.
("Funkcija" int
, je vedno sumljivejša in sumljivejša. Že od
+začetka smo v zvezi z njo dajali besedo "funkcija" pod narekovaje, zdaj pa vidimo,
+da zmore vedno več in več stvari. Pa še enako ji je ime kot tipu in funkcij, ki
+jim je ime enako kot tipom, je vedno več. Kakšna skrivnost se skriva za tem? To
+boste izvedeli v enem od prihodnjih napetih nadaljevanj Programiranja 1.)
Preštejmo torej še enkrat Benjaminove klice, tokrat s slovarjem s privzetimi + vrednostmi.
+ +import collections + +pogostosti = collections.defaultdict(int) +for ime in klici: + pogostosti[ime] += 1+ +
Ni to kul?
+ +Poglejmo si nekaj, kar je kul še bolj.
+ + +Preštevanje je pravzaprav tako pogosta reč, da obstaja zanj specializiran
+ tip. Tako kot defaultdict
je v modulu collections
,
+imenuje pa se Counter
.
>>> stevilo_klicev = collections.Counter(klici) +>>> stevilo_klicev +Counter({'Dani': 11, 'Berta': 9, 'Cilka': 5, 'Ana': 5})+ +
Komentirali ne bomo veliko, ker še ne znamo. Že ob tem, da sem temu rekel + tip, sem se moral ugrizniti v jezik, saj bi raje govoril o razredu. Kaj je + in kako deluje, pa nas še presega. Zna pa pravzaprav še veliko stvari, + tako da tem, ki jih zanima, priporočam, da si ga ogledajo. Mimogrede:
+ +>>> napis = "CVIVS IN HOC RENOVATA LOCO PIA FVLGET IMAGO SIS" \ + "CVSTOS POPVLI SANCTE IACOBE TVI" +>>> collections.Counter() +Counter({' ': 13, 'I': 8, 'O': 8, 'V': 7, 'A': 6, 'C': 6, 'S': 6, 'T': 5, 'E': 4, +'L': 3, 'N': 3, 'P': 3, 'G': 2, 'B': 1, 'F': 1, 'H': 1, 'M': 1, 'R': 1})+ +
Se pravi, da lahko kronogram rešimo tudi z
+ +def kronogram(s): + crke = collections.Counter(s) + return crke["I"] + 5 * crke["V"] + 10 * crke["X"] + 50 * crke["L"] + \ + 100 * crke["C"] + 500 * crke["D"] + 1000 * crke["M"]+ + + +
Množice so podobne seznamom, a s to razliko, da lahko vsebujejo vsak element + samo enkrat. Po drugi strani (in ne le po drugi strani, tudi tehnično) pa + so podobne slovarjem. Niso namreč urejene in vsebujejo lahko le elemente, + ki so nespremenljivi. Poleg tega pa lahko zelo hitro ugotovimo, ali množica + vsebuje določen element ali ne - tako kot lahko pri slovarjih hitro + ugotovimo, ali vsebujejo določen ključ ali ne.
+ +Množice zapišemo z zavitimi oklepaji, tako kot smo vajeni pri matematiki.
+danasnji_klici = {"Ana", "Cilka", "Eva"}+ +
Tako lahko sestavimo le neprazno množico. Če napišemo le oklepaj in
+ zaklepaj, {}
, pa dobimo slovar. (Čemu so se odločili, naj bo
+ to slovar, ne množica? Slovar je bil prej, množice je Python dobil kasneje.
+ Zato.) Če hočemo narediti prazno množico, rečemo
prazna = set()+ +
"Funkcija" set
je malo podobna "funkciji" int
:
+ damo ji lahko različne argumente, pa jih bo spremenila v množico. Damo ji
+ lahko, recimo, seznam, pa bomo dobili množico z vsemi elementi, ki se
+ pojavijo v njem.
>>> set([1, 2, 3]) +{1, 2, 3} +>>> set(range(5)) +{0, 1, 2, 3, 4} +>>> set([6, 42, 1, 3, 1, 1, 6]) +{1, 42, 3, 6}+ +
Mimogrede opazimo, da tudi množice, tako kot slovarji, res ne dajo nič na + vrstni red.
+ +Poleg seznamov lahko množicam podtaknemo karkoli, prek česar bi lahko šli
+ z zanko for
, recimo niz ali slovar.
>>> set("Benjamin") +{'a', 'B', 'e', 'i', 'j', 'm', 'n'} +>>> stevilke +{'Dani': '040 193831', 'Fanči': '040 135367', 'Iva': '040 222333', +'Helga': '+49 175 4728 475', 'Eva': '051 123123', 'Cilka': '041 103194', +'Berta': '040 318319', 'Ana': '041 310239'} +>>> set(stevilke) +{'Iva', 'Helga', 'Eva', 'Berta', 'Fanči', 'Dani', 'Cilka', 'Ana'}+ +
Spremenljivka stevilke
(še vedno) vsebuje slovar, katerega
+ ključi so imena Benjaminovih oboževalk. Ker zanka prek slovarja "vrača"
+ ključe, bo tudi množica, ki jo sestavimo iz slovarja, vsebovala ključe.
V množico lahko dodajamo elemente in vprašamo se lahko, ali množica vsebuje + določen element.
+ +>>> s = set("Benjamin") +>>> "e" in s +True +>>> "u" in s +False +>>> s.add("u") +>>> s +{'a', 'B', 'e', 'i', 'j', 'm', 'n', 'u'} +>>> "u" in s +True +>>> s.add("a") +>>> s.add("a") +>>> s.add("a") +>>> s +{'a', 'B', 'e', 'i', 'j', 'm', 'n', 'u'}+ +
Na koncu smo poskušali v množico dodati element, ki ga že vsebuje. To seveda + ne gre, množica vsak element vsebuje le enkrat.
+ +Če imamo dve množici, lahko izračunamo njuno unijo, presek, razliko...
+ +>>> u = {1, 2, 3} +>>> v = {3, 4, 5} +>>> u | v +{1, 2, 3, 4, 5} +>>> u & v +{3}+ +
Preverimo lahko tudi, ali je neka množica podmnožica (ali nadmnožica druge). + To najpreprosteje storimo kar z operatorji za primerjanje.
+ +>>> u = {1, 2, 3} +>>> {1, 2} <= u +True +>>> {1, 2, 3, 4} <= u +False +>>> {1, 2, 3} <= u +True +>>> {1, 2, 3} < u +False+ +
{1, 2, 3}
, je podmnožica u
-ja, ni pa njegove
+ prava podmnožica, saj vsebuje kar cel u
.
Z množicami je mogoče početi še marsikaj zanimivega - vendar bodi dovolj.
+ + +Recimo, da želimo sestaviti skupine datotek v nekem direktoriju glede na + končnice. Sestavili bomo slovar, katerega ključi bodo končnice, na primer + .py, .txt in .mp3, vrednosti pri vsakem ključu pa imena datotek s to + končnico.
+ +datoteke = {} +for ime in os.listdir(dir): + konc = os.path.splitext(ime)[1] + if not konc in datoteke: + datoteke[konc] = set() + datoteke[konc].add(ime)+ + +
Če ste bili pozorni, niste spregledali, da je gornji program pravzaprav na + nek način enak programu, s katerim smo preštevali, kolikokrat je Benjamin + klical katero od deklet: + +
pogostosti = {} +for ime in klici: + if not ime in pogostosti: + pogostosti[ime] = 0 + pogostosti[ime] += 1+ + +
"Istost" je v tem, da obakrat naredimo prazen slovar. Nato gremo z zanko
+for
čez neke reči. Za vsako reč (v gornjem primeru datoteke, v
+spodnjem ime dekleta) preverimo, ali je že v slovarju. Če je ni, jo dodamo tako,
+da ji damo neko privzeto vrednost (zgoraj prazno množico, spodaj 0). Nato
+pravkar dodano stvar posodobimo glede na trenutno reč (v gornjem primeru dodamo
+datoteko v pravkar sestavljeno ali od prej obstoječo množico, v spodnjem povečamo
+število klicev te osebe za 1).
Aja, to finto pa že poznamo. Slovarji s privzetimi vrednostmi!
+ +datoteke = collections.defaultdict(set) +for ime in os.listdir(dir): + konc = os.path.splitext(ime)[1] + datoteke[konc].add(ime)+ \ No newline at end of file -- cgit v1.2.1