Naloge (dodatne)
Najdaljša beseda
Napiši funkcijo najdaljsa(s)
, ki vrne najdaljšo besedo v nizu s
. Pomagajte si z metodo split()
.
>>> najdaljsa('an ban pet podgan')
'podgan'
Rešitev
def najdaljsa(s):
naj = ''
for beseda in s.split():
if len(beseda) > len(naj):
naj = beseda
return naj
Podobnost
Napišite funkcijo podobnost(s1, s2)
, ki izračuna podobnost med dvema nizoma. Podobnost
definirajmo kot število mest v katerih se niza ujemata.
sobota
robot
------
011110 -> 4
>>> podobnost('sobota', 'robot')
4
>>> podobnost('robot', 'sobota')
4
Rešitev
Uporabimo funkcijo zip.def podobnost(s1, s2):
stevec = 0
for c1, c2 in zip(s1, s2):
if c1 == c2:
stevec += 1
return stevec
Ker se v Pythonu vrednosti True in False obnašata kot števili 0 in 1, bi lahko program zapisali tudi takole:
def podobnost(s1, s2):
stevec = 0
for c1, c2 in zip(s1, s2):
stevec += c1 == c2
return stevec
Seveda se da tudi ta program skrajšati.
def podobnost(s1, s2):
return sum(c1 == c2 for c1, c2 in zip(s1, s2))
Sumljive besede
Napiši funkcijo sumljive(s)
, ki vrne seznam vseh sumljivih besed v danem nizu.
Beseda je sumljiva, če vsebuje tako črko u kot črko a.
>>> sumljive('Muha pa je rekla: "Tale juha se je pa res prilegla, najlepša huala," in odletela.')
['Muha', 'juha', 'huala,"']
Rešitev
def sumljive(s):
suspicious = []
for word in s.split():
if 'u' in word and 'a' in word:
suspicious.append(word)
return suspicious
Vsi
Napišite funkcijo vsi(xs)
, ki sprejme seznam xs
in vrne True
, če so
vse vrednosti v seznamu
resnične.
Elementi seznama xs
so lahko poljubnega tipa, ne le bool
.
>>> vsi([True, True, False])
False
>>> vsi([True, True])
True
>>> vsi([1, 2, 3, 0])
False
>>> vsi(['foo', 42, True])
True
>>> vsi([])
True
Rešitev
def vsi(xs):
for x in xs:
if not x:
return False
return True
Vsaj eden
Napišite funkcijo vsaj_eden
, ki deluje podobno kot vsi
, le da vrne
True
, če je vsaj ena vrednost v seznamu resnična.
>>> vsaj_eden([2, 3, 0])
True
>>> vsaj_eden([])
False
Rešitev
def vsaj_eden(xs):
for x in xs:
if x:
return True
return False
Multiplikativni range
Napišite funkcijo mrange(start, faktor, dolzina)
, ki vrne seznam, kjer je vsako naslednje število za
faktor večje od prejšnjega. Npr., v seznamu [1, 2, 4, 8, 16]
je vsako
naslednje število 2-krat večje od prejšnjega.
>>> print(mrange(7, 4, 7))
[7, 28, 112, 448, 1792, 7168, 28672]
Rešitev
def mrange(s, r, l):
xs = []
for i in range(l):
xs.append(s)
s *= r
return xs
Vsota seznamov
Podan je seznam seznamov, npr.
[[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]]
. Napiši funkcijo, ki v
seznamu vrne vsote vseh elementov v posameznih podseznamih. Za gornji
seznam naj funkcija vrne seznam [7, 4, 0, 10, 4]
, saj je, na primer,
2 + 4 + 1 = 7
.
>>> vsota_seznamov([[1, 1, 1], [1, 1]])
[3, 2]
>>> vsota_seznamov([[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]])
[7, 4, 0, 10, 4]
Rešitev
def vsota_seznamov(xss):
vsote = []
for xs in xss:
vsota = 0
for x in xs:
vsota += x
vsote.append(vsota)
return vsote
Ampak zakaj bi pisali na dolgo, če lahko napišemo tako:
def vsota_seznamov(xss):
return list(map(sum, xss))
Največji podseznam
Podan je podoben seznam kot zgoraj. Napiši funkcijo, ki vrne podseznam z
največjo vsoto elementov. Za gornji seznam mora funkcija vrniti
[8, 2]
, saj je to podseznam z največjo vsoto, namreč 10
.
>>> najvecji_podseznam([[1, 1, 1], [1, 1]])
[1, 1, 1]
>>> najvecji_podseznam([[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]])
[8, 2]
Rešitev
def najvecji_podseznam(xss):
najvecji = []
najvecji_vsota = float('-inf')
for xs in xss:
vsota = 0
for x in xs:
vsota += x
if vsota > najvecji_vsota:
najvecji = xs
najvecji_vsota = vsota
return najvecji
Pomagamo si lahko tudi s funkcijo iz prejšnje naloge.
def najvecji_podseznam(xss):
ys = vsota_seznamov(xss)
najvecji = float('-inf')
for i, y in enumerate(ys):
if y > ys[najvecji]:
najvecji = i
return xss[najvecji]
Ali krajše.
def najvecji_podseznam(xss):
return max(xss, key=sum)
Drugi največji
Napiši funkcijo, ki poišče in vrne drugi največji element seznama.
>>> drugi_najvecji([5, 1, 4, 2, 3])
4
Rešitev
def drugi_najvecji(xs):
prvi = drugi = float('-inf')
for x in xs:
if x > prvi:
drugi = prvi
prvi = x
elif x > drugi:
drugi = x
return drugi
Lahko pa seznam najprej uredimo, nato pa preberemo predzadnjo vrednost.
def drugi_najvecji(xs):
return sorted(xs)[-2]
Cezarjeva šifra
Napišite program, ki podan niz zašifrira z uporabo cezarjeve
šifre. Preden se
lotite naloge, se je morda vredno pozanimati kaj počneta funkciji
ord in
chr.
Predpostavite lahko, da niz s
vsebuje le male črke angleške besede in
presledke.
>>> cezar('the quick brown fox jumps over the lazy dog')
'wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj'
Rešitev
def cezar(s):
cipher = ''
for c in s:
if 'a' <= c <= 'w':
cipher += chr(ord(c) + 3)
elif 'x' <= c <= 'z':
cipher += chr(ord(c) - 23)
else:
cipher += c
return cipher
Nalogo `cezar` lahko rešimo tudi s parom funkcij `maketrans` in
`translate`.
def cezar(s):
alphabet = 'abcdefghijklmnopqrstuvwxyz'
trans = str.maketrans(alphabet, alphabet[3:] + alphabet[:3])
return s.translate(trans)
EMŠO
Napiši funkcijo veljavna
, ki preveri pravilnost dane številke EMŠO. Kako je
sestavljena pravilna številka EMŠO, je napisano v 4. členu Uredbe o
načinu določanja osebne identifikacijske
številke.
Preveriti morate pravilnost zadnje števke.
>>> veljavna('2902932505526')
True
>>> veljavna('2805985500156')
True
>>> veljavna('2805985505156')
False
Rešitev
def veljavna(emso):
vsota = 0
for i, e in zip((7, 6, 5, 4, 3, 2, 7, 6, 5, 4 ,3 ,2, 0), emso):
vsota += i * int(e)
ostanek = vsota % 11
if ostanek == 0:
return e == str(ostanek)
else:
return e == str(11 - ostanek)