Projekt Pronal Projekt Pronal

Kazalo:
Sofinasiranje projekta
Starejši - zbirka nalog...
Tekmovanja...
Tekmovanja - dopolni...
Tekmovanja - Parsons...
Tekmovanja - popravi...
Starejši - učbenik
Funkcije
If stavek
Izpisi
Množice
Nizi
Pisanje in popravljanje programa
Seznami in nizi
Slovarji
Spoznajmo Python
Uvod v funkcije
Zanka for
Zanka while
Slovarji

Slovarji


Uporaba slovarjev - razlaga

V slovarjih shranjujemo pare (ključ, vrednost), kjer vsakemu ključu pripada določena vrednost:

slovar = {ključ1: vrednost1, ključ2: vrednost2, ključ3: vrednost3,...}

Prazen slovar zapišemo kot:

slovar = {}

ali kot:

slovar = dict()

V že definiran slovar dodajamo nove ključe in pripadajoče vrednosti tako:

slovar[ključ] = vrednost

kjer se vrednost ključa, če se ta v slovarju že nahaja, prepiše z novo vrednostjo.

Če želimo kak ključ in njemu pripadajočo vrednost iz slovarja izbrisati, uporabimo ukaz:

del slovar[ključ]

Recimo, da želimo speči palačinke, za kar potrebujemo 100 gramov moke, 2 jajci in 300 mililitrov mleka. Definiramo slovar, ki ga shranimo v vrednost palacinke, pri čemer se malce zmotimo in vnesemo napačno število jajc, v recept dodamo 1 gram popra, ki ga pri pripravi palačink ne potrebujemo, ter pozabimo dodati mleko.

palacinke = {'moka': 100, 'jajca': 4, 'poper': 1}

Ker ne potrebujemo 4 jajc, ampak le 2, to popravimo:

palacinke['jajca'] = 2

Ker popra ne potrebujemo, ga iz slovarja odstranimo:

del palacinke['poper']

Pozabljeno mleko, dodamo:

palacinke['mleko'] = 300

Poglejmo sedaj, kako izgleda slovar palacinke:

>>> palacinke
{'moka': 100, 'jajca': 2, 'mleko': 300}

V slovar lahko dodamo več ključev in pripadajočih vrednosti naenkrat. Definiramo lahko na primer nov slovar, sestoječ iz 100 g marmelade in 10 gramov sladkorja, ki ga shranimo v spremenljivko dodatki_k_palacinkam:

dodatki_k_palacinkam = {'marmelada': 100, 'sladkor': 10}

in slovar sestavin, ki jih potrebujemo za pripravo palačink razširimo z dodatki:

palacinke.update(dodatki_k_palacinkam)

Pri tem se slovarju palacinke dodajo vsi ključi in pripadaoče vrednosti iz slovarja dodatki_k_palacinkam:

>>> palacinke
{'moka': 100, 'jajca': 2, 'mleko': 300, 'marmelada': 100, 'sladkor': 10}

Če nas zanima vrednost posameznega ključa, recimo količina moke v receptu za palačinke, to poizvemo na naslednji način:

>>> palacinke['moka']
100

V primeru, da se iskani ključ v slovarju ne nahaja, se bo pri izvedbi zgornjega klica izvajanje programa ustavilo, na zaslon pa se bo izpisala napaka. Če se želimo temu izgoniti, lahko do vrednosti ključev dostopamo tudi z vgrajeno metodo get:

>>> palacinke.get('moka')
100

Metoda get lahko sprejme enega ali dva argumenta in je zelo uporabna, kadar nismo prepričani, ali se določen ključ v slovarju nahaja. Če iskanega ključa v slovarju ni, se izvajanje programa ne bo ustavilo, bo pa zgornji izraz dobil vrednost None.

vrednost = palacinke.get('poper')
>>> vrednost
None

Metodi get lahko podamo še drugi argument in s tem sami določimo, kakšno vrednost bo dobil zgornji izraz, v primeru, da iskanega ključa v slovarju ni. Če želimo, da se v tem primeru na zaslon izpiše primerno sporočilo, lahko zapišemo:

>>> palacinke.get('poper', 'Popra v receptu ne potrebujete!')
'Popra v receptu ne potrebujete!'

oziroma:

vrednost = palacinke.get('poper', 'Popra v receptu ne potrebujete!')
>>> vrednost
'Popra v receptu ne potrebujete!'

V primeru, da se ključ v slovarju nahaja, pa kot rezultat takega klica dobimo vrednost, ki pripada temu ključu:

>>> palacinke.get('jajca', 'Jajc v receptu ne potrebujete!')
2

oziroma:

vrednost = palacinke.get('jajca', 'Jajc v receptu ne potrebujete!')
>>> vrednost
2

Če nas zanima število ključev v slovarju, to poizvemo z ukazom:

>>> len(palacinke)
5

Kadar se moramo sprehoditi, čez vse ključe v slovarju, na primer če želimo dobiti izpis vseh sestavin v palačinkah, lahko to naredimo s preprosto zanko:

>>> for sestavina in palacinke.keys():
      print(sestavina)

'moka'
'jajca'
'mleko'
'marmelada'
'sladkor'

ali pa kar:

>>> for sestavina in palacinke:
      print(sestavina)

'moka'
'jajca'
'mleko'
'marmelada'
'sladkor'

Kadar se moramo sprehoditi, čez vse vrednosti v slovarju, lahko to spet naredimo z zanko:

>>> for vrednost in palacinke.values():
      print(vrednost)

100
2
300
100
10

Lahko pa do ključev in vrednosti dostopamo tudi sočasno:

>>> for (ključ, vrednost) in palacinke.items():
      print(ključ, vrednost)

'moka' 100
'jajca' 2
'mleko' 300
'marmelada' 100
'sladkor' 10

Kadar želimo dobiti seznam vseh ključev ali seznam vseh vrednosti, ki se nahajajo v slovarju, lahko uporabimo vgrajeno funkcijo list:

>>> list(palacinke.keys())
['moka', 'jajca', 'mleko', 'marmelada', 'sladkor']

>>> list(palacinke.values())
[100, 2, 300, 100, 10]

Slovar lahko spremenimo v seznam parov [(ključ1, vrednost1), (ključ2, vrednost2), (ključ3, vrednost3), ...], čemur rečemo asociativni seznam:

seznam_parov = list(palacinke.items())
>>> seznam_parov
[('moka', 100), ('jajca', 2), ('mleko', 300), ('marmelada', 100), ('sladkor', 10)]

Asociativne sezname lahko spremenimo nazaj v slovarje z vgrajeno funkcijo dict:

>>> dict(seznam_parov)
{'moka': 100, 'jajca': 2, 'mleko': 300, 'marmelada': 100, 'sladkor': 10}

Podnobno, kot se da narediti izpeljane sezname, lahko naredimo tudi izpeljane slovarje. Te lahko naredimo na dva načina. Recimo, da želimo narediti slovar, v katerem se nahaja 5 ključev, kjer je vsak predstavljen s celim številom med 1 in 5, pri čemer vsakemu pripada vrednost, ki je kvadrat tega števila.

Prvi način je, da najprej naredimo izpeljani asociativni seznam:

seznam = [(i, i**2) for i in range(1, 6)]

In ga nato pretvorimo v slovar:

>>> dict(seznam)
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

Drugi način je, da že takoj naredimo slovar:

slovar = {i: i**2 for i in range(1, 6)}
>>> slovar
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

Slovarji nimajo vrstnega reda. Spodnja dva slovarja sta iz tega razloga ekvivalentna.

>>> {'moka': 100, 'jajca': 2, 'mleko': 300} == {'mleko': 300, 'moka': 100, 'jajca': 2}
True

Zbiranje osebnih podatkov

V "Uporaba slovarjev - razlaga" si lahko preberete, kako v Pythonu delamo s slovarji.

Tu pa rešite nekaj osnovnih nalog iz te teme.

V nekem podjetju zbirajo podatke o osebah, ki brskajo po medmrežju. Podatki so shranjeni v slovarjih (en slovar za vsako osebo). Ključ v takem slovarju je lastnost, vrednosti pa podatek o tej lastnosti za določeno osebo. Primeri takšnih slovarjev:

oseba1 = {'ime': 'Božidar', 'telefon': '031918211',
          'obiskane spletne strani': ['facebook.com', 'google.com']}
oseba2 = {'naslov': 'Dunajska 105', 'številka noge': 42,
          'prijatelji': ['Marko', 'Ana']}

1. podnaloga

Sestavite funkcijo podatek(oseba, lastnost), ki vrne podatek o lastnosti lastnost, ki jo imamo v slovarju oseba. Funkcija naj vrne None, če se ta podatek v slovarju ne nahaja. Primer:

>>> podatek({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, 'naslov')
'Dunajska 105'
>>> podatek({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, 'prijatelji')
None

Pri tem ne smete uporabiti metode get!

Uradna rešitev

def podatek(oseba, lastnost):
    """Vrne podatek o lastnosti lastnost oz. None."""
    if lastnost not in oseba:
        return None
    return oseba[lastnost]

2. podnaloga

Sestavite funkcijo podatek_get(oseba, lastnost), ki vrne podatek o lastnosti lastnost, ki jo imamo v slovarju oseba. Funkcija naj vrne None, če se ta podatek v slovarju ne nahaja. Primer:

>>> podatek_get({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, 'naslov')
'Dunajska 105'
>>> podatek_get({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, 'prijatelji')
None

Pri tem si nujno pomagajte z metodo get.

Uradna rešitev

def podatek_get(oseba, lastnost):
    """Vrne podatek o lastnosti lastnost oz. None."""
    return oseba.get(lastnost, None)

3. podnaloga

Kadar oseba spremeni kak osebni podatek, moramo ta podatek v slovarju popraviti. Napišite funkcijo popravi(oseba, lastnost, podatek), ki poleg slovarja oseba, sprejme lastnost in podatek o tej lastnosti ter podatek posodobi in vrne spremenjen slovar. Če lastnosti v slovarju ni, jo doda. Zgled:

>>> popravi({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, 'naslov', 'Slovenska 5')
{'ime': 'Božidar', 'naslov': 'Slovenska 5'}

>>> popravi({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, 'prijatelji', {'Nina', 'Vito'})
{'ime': 'Božidar', 'naslov': 'Dunajska 105', 'prijatelji': {'Nina', 'Vito'}}

Uradna rešitev

def popravi(oseba, lastnost, podatek):
    """Spremeni podatek o lastnosti na novo vrednost in vrne spremenjen slovar."""
    oseba[lastnost] = podatek
    return oseba

4. podnaloga

Oseba lahko spremeni tudi več osebnih podatkov naenkrat. Takrat moramo popraviti vse spremenjene podatke v slovarju. Napišite funkcijo popravi_vec(oseba, novi), ki poleg slovarja oseba, sprejme slovar novi, v katerem so vse lastnosti in pripadajoči podatki, ki jih po moramo popraviti in vrne spremenjen slovar. Če kakšnih lastnosti v slovarju ni, jih doda. Zgled:

>>> popravi_vec({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, {'naslov': 'Slovenska 5', 'prijatelji': {'Nina', 'Vito'}})
{'ime': 'Božidar', 'naslov': 'Slovenska 5', 'prijatelji': {'Nina', 'Vito'}}

Namig: pomagate si lahko z metodo update.

Uradna rešitev

def popravi_vec(oseba, novi):
    """Posodobi slovar oseba z lastnostmi iz slovarja novi in vrne posodobljen slovar oseba."""
    oseba.update(novi)
    return oseba

5. podnaloga

Včasih kaka lastnost o določeni osebi ne drži več. Takrat jo moramo iz slovarja neumudoma izbrisati, čeprav nimamo njene nove vrednosti. Napišite funkcijo izbrisi(oseba, lastnost), ki poleg slovarja oseba, sprejme lastnost lastnost ter jo iz slovarja izbriše in vrne spremenjen slovar. Če lastnosti v slovarju ni, samo vrne vhodni slovar. Zgled:

>>> izbrisi({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, 'naslov')
{'ime': 'Božidar'}

>>> izbrisi({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, 'prijatelji')
{'ime': 'Božidar', 'naslov': 'Dunajska 105'}

Uradna rešitev

def izbrisi(oseba, lastnost):
    """Izbriše lastnost iz slovarja in vrne spremenjen slovar."""
    if oseba.get(lastnost):
        del oseba[lastnost]
    return oseba

6. podnaloga

Napišite funkcijo ista_oseba(oseba1, oseba2), ki pove, ali slovarja oseba1 in oseba2 predstavljata isto osebo. Isto oseba predstavljata takrat, kadar vsebujeta iste lastnosti z istimi vrednostmi. Zgled:

>>> ista_oseba({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, {'ime': 'Sara', 'naslov': 'Dunajska 105'})
False

>>> ista_oseba({'ime': 'Božidar', 'naslov': 'Dunajska 105'}, {'naslov': 'Dunajska 105', 'ime': 'Božidar',})
True

Namig: lahko si pomagate z operatorjem ==.

Uradna rešitev

def ista_oseba(oseba1, oseba2):
    """Ali slovarja oseba1 in oseba2 predstavljata isto osebo?"""
    return oseba1 == oseba2

7. podnaloga

Za osebi oseba1 in oseba2 pravimo, da se ujemata v lastnosti lastnost, če za obe osebi poznamo podatka o tej lastnosti in sta podatka enaka. Če pa za obe osebi poznamo podatka in sta podatka različna, pa pravimo, da se osebi razlikujeta v lastnosti lastnost. Na primer, osebi

oseba1 = {'ime': 'Janez', 'priimek': 'Novak'}
oseba2 = {'ime': 'Jože', 'priimek': 'Novak', 'starost': 20}

se ujemata v lastnosti 'priimek' in razlikujeta v lastnosti 'ime'. (V lastnosti 'starost' se niti ne ujemata niti ne razlikujeta.)

Sestavite funkcijo ujemanje(oseba1, oseba2), ki pove, v koliko lastnostih se osebi oseba1 in oseba2 ujemata in v koliko lastnostih se razlikujeta. Rezultat naj funkcija vrne kot tabelo z dvema elementoma. Primer:

>>> ujemanje({'ime': 'Janez', 'priimek': 'Novak'},
             {'ime': 'Jože', 'priimek': 'Novak', 'starost': 20})
[1, 1]

Namig: uporabite zanko for.

Uradna rešitev

def ujemanje(oseba1, oseba2):
    """V koliko lastnostih se osebi ujemata in razlikujeta?"""
    ujema = 0
    razlikuje = 0
    for lastnost in oseba1: # preverimo vse lastnosti prve osebe
        if lastnost in oseba2: # če gre za skupno lastnost
            if oseba1[lastnost] == oseba2[lastnost]:
                ujema += 1
            else:
                razlikuje += 1
    return [ujema, razlikuje]
Mesto objave ob koncu projekta 15.9.2018