Imejmo seznam klicev, tako kot na predavanjih. Na primer

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']

Obvezna naloga

Napiši funkcijo razporedi_po_klicih(klici), ki prejme seznam, kot je gornji in vrne slovar, katerega ključi so število klicev, pripadajoče vrednosti pa seznami oseb, ki jih je Benjamin tolikokrat poklical. Če pokličemo funkcijo z gornjim seznamom, mora vrniti slovar {11: ['Dani'], 9: ['Berta'], 5: ['Ana', 'Cilka']}, saj je enajstkrat poklical Dani, devetkrat Berto in petkrat Ano in Cilko.

Če jih podamo prazen seznam klicev, vrne prazen slovar.

Namig: najprej preštej klice. Nato predelaj dobljeni slovar. Spomni se predavanj.

Napiši tudi funkcijo najveckrat_klicane(klici), ki vrne seznam tistih, ki jih je največkrat klical. V gornjem primeru bi vrnila seznam Dani. Če h klici dodamo še dva klica Berte, tako da bo obe poklical po enajstkrat, funkcija vrne ["Berta", "Dani"]. Če funkciji podamo prazen seznam klicev, vrne prazen seznam.

Namig: lahko si pomagaš tako, da pokličeš prejšnjo funkcijo.

Napiši še funkcijo preveri_vrsto(klici, vrstni_red). Funkcija preveri vrstni_red: vrstni red je pravilen (in funkcija vrne True), če se nikoli ne zgodi, da bi bila oseba, ki jo je poklical manjkrat, pred osebo, ki jo je poklical večkrat. Pri tem ni nujno, da so v seznamu vrstni_red vse osebe. Za gornji seznam klicev bi bili pravilni, recimo, vrstni redi ["Dani", "Berta", "Ana", "Cilka"], ["Dani", "Berta", "Ana", "Cilka"] in tudi ["Dani", Ana", "Cilka"], ne pa ["Ana", "Dani", "Berta", Cilka"].

Dodatna naloga

Napiši funkcijo uredi(klici), ki vrne seznam imen, urejen po padajočem številu klicev. Če je dve klical enakokrat, naj ju uredi abecedi. Za gornji seznam klicev mora vrniti ["Dani", "Berta", "Ana", "Cilka"].

Rešitev

Morda najprej sprogramirajmo funkcijo prestej(klici), ki vrne slovar, katerega ključi so vsa imena, ki se pojavijo v klici, pripadajoče vrednosti pa so število pojavitev.

import collections

def prestej(klici):
    stevci = collections.defaultdict(int)
    for ime in klici:
        stevci[ime] += 1
    return stevci

Ne le, da smo prav takšno funkcijo napisali že na predavanjih: v resnici takšno funkcijo Python že ima. Najdemo jo v modulo (kje pa drugje) collections, imenuje se Counter. A ostanimo pri naši prestej.

Funkcija razporedi_po_klicih mora sestaviti slovar, katerega ključi so števila klicev, vrednosti pa imena, ki so bila tolikokrat poklicana. Najprej lahko pokličemo prestej, nato pa gremo prek parov (ime, število klicev) in k seznamu, ki pripada temu številu klicev, dodamo ime.

Spet nam pride defaultdict tako prav, da je že kar nevzgojno. :)

def razporedi_po_klicih(klici):
    po_klicih = collections.defaultdict(list)
    for ime, stevilo in prestej(klici).items():
        po_klicih[stevilo].append(ime)
    return po_klicih

Seznam največkrat klicanih, ki ga mora vrniti najveckrat_klicane, zdaj le pokliče prejšnjo funkcijo. Vzame največji ključ in vrne seznam, ki pripada temu ključu. Pa še mimogrede ga uredi, ker naloga pač tako hoče.

Edina sitnost je, da je seznam klicev lahko tudi prazen. Za to poskrbimo na začetku.

def najveckrat_klicane(klici):
    if not klici:
        return []
    po_klicih = razporedi_po_klicih(klici)
    return sorted(po_klicih[max(po_klicih)])

Vrsto preverimo tako, da preštejemo klice. Potem gremo po vseh parih in preverimo, da se pri katerem slučajno ne zgodi, da bi imel ta, ki je v seznamu prej, več klicev kot oni, ki je za njim. V tem primeru vrnemo False. Če je vse v redu, pa na koncu vrnemo True.

def preveri_vrsto(klici, vrsta):
    stevci = prestej(klici)
    for ena, druga in zip(vrsta, vrsta[1:]):
        if stevci[ena] < stevci[druga]:
            return False
    return True

Dodatna naloga, urejanje po klicih je pravzaprav preprostejša od prejšnjih. Naj bo po_klicih slovar, ki ga dobimo z razporedi_po_klicih. Vzamemo pare ključ vrednost (po_klicih.items()) in jih razporedimo po vrsti (sorted(po_klicih.items())). Ker bo tole urejeno naraščajoče, mi pa želimo padajoč vrstni red, vse skupaj še obrnemo (sorted(po_klicih.items())[::-1]). Sprehodimo se čez to reč in imena dodajamo v seznam.

def uredi(klici):
    po_klicih = razporedi_po_klicih(klici)
    red = []
    for stevilo, imena in sorted(po_klicih.items())[::-1]:
        red += sorted(imena)
    return red

[::-1] se lahko izognemo tako, da sortiranju naročimo padajoče urejanje:

for stevilo, imena in sorted(po_klicih.items(), reverse=True):
마지막 수정됨: 화요일, 24 2월 2026, 5:53 PM