Python - zanka for

Python - zanka "for"

Avtor: Dani Sajtl

Spomnimo se ...

... kako bi lahko naredili v Pythonu neko stvar večkrat? Npr. radi bi izpisali vsa števila od 1 do 100.

Brez uporabe zanke while

Takoj potem, ko smo spoznali stavek za izpisovanje, bi nalogo rešili takole:

print (1)
print (2)
print (3)
...
print (99)
print (100)

Z uporabo zanke while

Prejšnja "rešitev" ni pustila v nas kakšnega posebnega navdušenja, zato smo kmalu spoznali pravo rešitev - zanko while, s katero bi nalogo rešili takole:

stevilo = 1
while stevilo < 101 :
   print (stevilo)
   stevilo += 1

Zanka for

While zanka je zelo fleksibilna. Lahko jo uporabimo za ponavljanje bloka kode, ko je katerikoli pogoj v njej izpolnjen. To je v splošnem zelo koristno, vendar pa bi včasih potrebovali še kaj drugega, npr. izvedli blok kode za vsak element v zaporedju. V takih primerih pa nam priskoči na pomoč zanka for.

Zanka for je najbolj uporabljan konstrukt za zankanje v Pythonu. Je zelo zmogljiva, sintaksa pa drugačna od večine drugih programskih jezikov - veliko bolj sledi naravnemu jeziku.

Najbolj pogosta oblika ponavljanja je zankanje čez vse člane niza ali seznama.

 
Sestava stavka for

for element in seznam :
Sledi zamaknjen blok kode z navodili kaj bomo naredili z elementom.

Tekom prve izvedbe bloka kode v zanki zavzame spremenljivka element prvi element v seznamu in je na voljo bloku kode v zanki. Ob drugi izvedbi bloka kode v zanki zavzame spremenljivka element vrednost drugega elementa v seznamu itd.


V nadaljevanju si poglejmo nekaj zgledov.

Zgled 1

Izračunajmo prvih 10 potenc števila 2.

for n in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] :
   print ("2 na", str(n), "je", str(2**n))


Rezultat:

>>>
2 na 1 je 2
2 na 2 je 4
2 na 3 je 8
2 na 4 je 16
2 na 5 je 32
2 na 6 je 64
2 na 7 je 128
2 na 8 je 256
2 na 9 je 512
2 na 10 je 1024


 
Element n zavzame v prvem koraku vrednost 1, ki se nato uporabi v jedru zanke kot eksponent za izračun potence z osnovo števila 2. V naslednjem koraku zavzame element n vrednost 2 in spet se ponovi stavek print itd.

Zgled 2

Dan je niz, v katerem so vsi samoglasniki (kot male črke). Za vsak znak v nizu izpiši znak in njegovo kodo.

for znak in "aeiou" :
   print (znak, ord(znak))


Rezultat:

>>>
a 97
e 101
i 105
o 111
u 117


 
Element (znak) se "sprehodi" po vseh samoglasnikih. Zanka izpiše za vsak znak v nizu kodo znaka kodo znaka (skrij) .

Zgled 3

V seznamu [3, "77", 23, 14.0, "Stevilo1", 49, 64, 70] poišči vsa cela števila deljiva s 7!


 
V seznamu niso nujno le števila, zato s pomočjo funkcije isinstance isinstance (skrij) le-to preveri.


seznam = [3, "77", 23, 14.0, "Stevilo1", 49, 64, 70]
for x in seznam :
   if isinstance(x, int) :
      if x % 7 == 0 :
         print("Našel sem celo število deljivo s 7: ", x)


Rezultat:

>>>
Našel sem celo število deljivo s 7:  49
Našel sem celo število deljivo s 7:  70


 
Za vsak element seznama zanka for izvede naslednje: s funkcijo isinstance se preveri ali je element seznama celo število; če je, preverimo še ostanek deljenja s 7. Zadnji if stavek se izvede, ko je ostanek deljenja s 7 enak 0.

Prikaži informacije 1 Skrij informacije 1

Prikaži kodo Skrij kodo

Prikaži rezultat Skrij rezultat

Prikaži informacije 2 Skrij informacije 2


isinstance(3, int)
>>>
True

Funkcija isinstance vrne True, če število 3 spada med cela števila.

isinstance(4.2, float)
>>>
True

Funkcija isinstance vrne True, če število 4.2 spada med decimalna števila.

isinstance("stevilo", str)
>>>
True

Funkcija isinstance vrne True, če je "stevilo" niz.

Zgled 4

Stavek "Danes je lep sončen dan." izpiši tako, da bi imeli za vsakim znakom še en presledek. Za zadnjim znakom v stavku je lahko presledek.

stavek = "Danes je lep sončen dan."
for znak in stavek :
   print (znak, end=" ")


Rezultat:

>>>
D a n e s   j e   l e p   s o n č e n   d a n .


 
V prvi iteraciji zanke for zavzame znak prvo črko stavka - torej črko D, ki se s funkcijo print izpiše. Naslednji izpis pa se ne začne v novi vrsti, ampak za znakom za presledek - določilo end. V drugi ponovitvi zanke for je v znaku druga črka - a, ki se izpiše takoj za prvo črko stavka in presledkom. Postopek se nadaljuje do konca podanega stavka (tudi za piko se doda presledek).

Zgled 5

Izračunaj vsoto števil od 1 do 10 zapisanih v seznamu (števili 1 in 10 sta vključeni zraven). Predpostavi, da so v seznamu res samo števila.

vsota = 0
for stevilo in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] :
   vsota += stevilo
print ("Vsota števil od 1 do 10 je: ", vsota)


Rezultat:

>>>
Vsota števil od 1 do 10 je:  55


 
Na začetku nastavimo vsoto na 0. V zanki for število najprej zavzame vrednost 1, ki se v jedru zanke prišteje k vsoti - torej je vsota 1. V naslednji iteraciji zanke for je v spremenljivki stevilo številka 2, ki se v jedru zanke prišteje k vsoti - torej je vsota 3. Postopek zanka for ponavlja do zadnjega elementa v seznamu - številke 10. Izpis vsote je izveden na koncu in je seveda zunaj zanke for.

Range

V dveh prej navednih zgledih je imela zanka for opraviti s seznamom števil v katerem so bila vsa števila od 1 do 10. Kaj pa, če bi imeli v seznamu precej večji obseg števil, npr. od 1 do 1000? Bi se namučili s tipkanjem, kajne?

Seveda ima Python v rokavu rešitev tudi za takšne primere. Funkcija se imenuje range, ki zna ustvariti sezname.

 
Funkcija range

range([začetek], konec[, korak])

Range je zmogljiva funkcija za ustvarjanje seznamov, ki vsebujejo aritmetično zaporedje. Največ se uporablja v zankah for. Argumenti morajo biti cela števila. Argument korak je opcijski. V primeru, da ga izpustimo, ima privzeto vrednost 1. Lahko je tudi negativen. Prav tako je argument začetek opcijski. V primeru, da ga izpustimo ima privzeto vrednost 0. Edini argument, ki je obvezen je konec. V polni obliki funkcija range vrne seznam celih števil [začetek, začetek + korak, začetek + 2 * korak, ...]. Korak ne sme biti 0.

Range (primer)

Če potrebujemo indekse elementov seznama, nam prav tako lahko pomaga range. Poglejmo si primer, v katerem se vsakemu elementu seznama vrednost poveča za 1:

seznam = [3, 7, -14, 5]
for ind in range(len(seznam)) :
   seznam[ind] = seznam[ind] + 1
print (seznam)


Rezultat:

>>>
[4, 8, -13, 6]


 
Dolžina seznama je 4, zato range vrne aritmetično zaporedje [0, 1, 2, 3]. V prvem koraku se vrednost elementa v seznamu z indeksom 0 poveča za 1, v drugem koraku se vrednost elementa v seznamu z indeksom 1 poveča za 1 itd.

Z range do seznama

Range ne vrne običajnega seznama, ampak objekt, ki zna šteti.

 
list(range(...))
Vrne seznam števil, ki jih dobimo pri štetju s pomočjo funkcije range.


Z ukazom print(range(10)) ne dobimo željenega rezultata:

>>> print(range(10))
range(0, 10)


Z ukazom list(range(10)) pa dobimo seznam (v našem primeru 10 števil):

>>> print(list(range(10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


 
range (10) vrne elemente od 0 do 9 in NE od 1 do 10, kot bi mogoče pričakovali.

Range (primeri)

Nekaj primerov uporabe funkcije range:

>>> print(list(range(0, 10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(list(range(1, 11)))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> print(list(range(0, 30, 5)))
[0, 5, 10, 15, 20, 25]
>>> print(list(range(0, 10, 3)))
[0, 3, 6, 9]
>>> print(list(range(0, -10, -1)))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> print(list(range(40, 10, -3)))
[40, 37, 34, 31, 28, 25, 22, 19, 16, 13]
>>> print(list(range(0)))
[]
>>> print(list(range(1, 0)))
[]
>>> print(list(range(-10, -100, -30)))
[-10, -40, -70]


 
range(0) ne vrne nobenega elementa, prav tako ne vrne nobenega elementa range(1, 0), ker je korak še vedno +1.


Ustvarimo seznama sodih števil in lihih števil do 50:

>>> sezLiha = list(range(1, 50, 2))
>>> print (sezLiha)
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49]
>>> sezSoda = list(range(2, 52, 2))
>>> print (sezSoda)
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50]

Naloga Bum!

Bruci matematike so utrjevali poštevanko in se igrali igrico "Bum!". Igra poteka tako, da v krogu štejejo od 1 dalje tako, da vsak pove naslednje večje število. Izjema so mnogokratniki števila 3 in pa tista števila, ki vsebujejo števko 3. Tedaj študent, ki je na vrsti, namesto števila zavpije: "Bum!" Napiši program, ki bo brucom pomagal pravilno šteti pri tej igrici.

Primer:

Do kod naj štejem? 13
1
2
Bum!
4
5
Bum!
7
8
Bum!
10
11
Bum!
Bum!


 
Ali znamo izpisati števila od 1 do npr. 13? Uporabimo zanko for, s funkcijo range pa določimo območje do kod štejemo. Sedaj moramo samo še razmisliti kdaj bomo izpisali trenutno število in kdaj niz "Bum!". Število do kod naj štejemo preberemo s funkcijo input.

Rešitev naloge Bum!

 
Na začetku preberemo število do kod bomo šteli v igrici. Shranimo jo v spremenljivko n in kar takoj pretvorimo v celo število z ukazom int.


vsota = 0
n = int(input("Do kod naj štejem? "))


 
Za štetje bomo uporabili zanko for, ki se bo "sprehodila" od števila 1 do števila n. Za določitev tega območja uporabimo funkcijo range z začetnim argumentom 1 in končnim argumentom n+1.


for i in range(1, n+1) :


 
Niz "Bum!" izpišemo takrat, ko imamo mnogokratnik števila 3 - ostanek pri deljenju s 3 je 0 (i % 3 == 0) ali pa pri tistih številih, ki vsebujejo števko 3 - ali se niz "3" nahaja v nizu i ("3" in str(i)).


    if i % 3 == 0 or "3" in str(i) :
        print ("Bum!")


 
Drugače pa izpišemo trenutno število.


    else :
        print(i)

Naloga putke Amalije

Putka Amalija se pripravlja na dolgo zimo. Vsak dan v kaščo spravi tri zrna koruze. Napiši program, ki prebere, koliko dni je Amalija nabirala zrna, nato pa nariše zalogo v njeni kašči, kakor vidiš na spodnjem primeru. Za vsako zrno izpiši eno črko "o", ograjice pa so iz znakov "#". Kašča je vedno široka 10 enot, višina pa se prilagodi količini koruze.

Primer: Koliko dni je Amalija nabirala zrnje? 9

############
#ooooooo   #
#oooooooooo#
#oooooooooo#
############

Razmislek na začetku

  • Nalogo bomo lažje rešili, če bomo problem zastavili po vrsticah.
  • Iz primera je razvidno, da imamo tri variante vrstic:

    • prva in zadnja vrstica je ograja sestavljena iz 12-ih znakov #,
    • lahko nimamo ali pa imamo eno ali več polnih vrstic sestavljenih iz znaka # na začetku in koncu ter vmes 10 znakov o,
    • lahko nimamo ali pa imamo največ eno vrstico sestavljenih iz znaka # na začetku in koncu in vmes manj kot 10 znakov o.
  • Za vrstico bi bilo dobro imeti funkcijo, ki bi nam vrnila ustrezno vrstico napolnjeno z n znaki, pri čemer je n število zrn (največ 10).

Potek reševanja naloge

Razširitev naloge

Nalogo bi lahko naredili tudi bolj splošno. Kašča bi lahko bila široka x enot, putka Amalija bi lahko vsak dan spravila v kaščo y zrn, ograja pa bi lahko bila sestavljena iz poljubnega znaka. Poleg števila dni nabiranja zrn bi se ti podatki prebrali na začetku izvajanja programa ali pa bi se program izvedel s klicem funkcije, npr. kasca(sirinaKasce, stDni, zrnNaDan, ograja).

Vprašanje 1

Programski jezik Python pozna poleg zanke while še eno zanko, ki je najbolj uporabljan konstrukt za zankanje v Pythonu. Kako se imenuje ta zanka?


Preveri

Pravilno

For zanka se poleg zanke while največ uporablja. Kar tako naprej.

Naprej

Napačno

For zanka je poleg zanke while najbolj uporabljan konstrukt za zankanje v Pythonu. Si boš sedaj to zapomnil(a)?

Še enkrat mi pokaži vprašanje Da, gremo naprej

Vprašanje 2

seznam = [3, 7, -14, 5]
for ind in range(len(seznam)) :
    seznam[ind] +=
print (seznam)

Za koliko se vsakemu elementu seznama poveča vrednost v zgornjem programčku?

Preveri

Pravilno

Odlično! Le tako naprej.

Naprej

Napačno

Ne, ne! V tretji vrstici kode se skriva pravilen odgovor. Vsakemu elementu seznama se poveča vrednost za !

Naprej

Vprašanje 3

V katerem območju vrne elemente range ()?

od 0 do
od 1 do
od 0 do
od 1 do

Pravilno

Tako se odgovarja! Bravo!

Naprej

Napačno

Še si bo treba pogledati ukaz range! Pravilen odgovor: od 0 do

Naprej

Vprašanje 4

Kateri konstrukti niso zanke v programskem jeziku Python? Označi vsaj en odgovor!


Preveri

Pravilno



Naprej

Napačno


Pravilno odkljukanih in pravilno neodkljukanih odgovorov:
Pravilno odkljukanih odgovorov:

Naprej

Vprašanje 5

Dopolnite program v Pythonu tako, da se bo izpisala beseda Vesolje s presledki med črkami:

V e s o l j e

beseda = ""
znak in beseda :
    print (, end=" ")

Preveri

Pravilno

Odlično! Tvoj program deluje prav. Sledi še zadnje vprašanje.

Naprej

Delno pravilno

Ni slabo, ampak vse pa tudi ni prav. Natančnejši pregled odgovorov bo podan na koncu vseh vprašanj.

Naprej

Napačno

Samo tri kratke nize je potrebno vpisati. Gre za zelo enostaven program. Ni težko.

Poskusi še enkrat Naprej

Vprašanje 6

list(range(...)) vrne seznam števil, ki jih dobimo pri štetju s pomočjo funkcije range. Poveži list(range(...)) z ustreznimi rezultati izpisa.

list(range(3, 7))
list(range(5, 3))
list(range(2, 10))
list(range(0, 10, 2))
list(range(5, 0, -1))
[3, 4, 5, 6]
[]
[2, 3, 4, 5, 6, 7, 8, 9]
[0, 2, 4, 6, 8]
[5, 4, 3, 2, 1]


Preveri

Pravilno

Bravo! Vsi pari so pravilno povezani.

Rezultati kviza

Napačno

Še bo potrebno malo vaje, da bo vse pravilno povezano.
Število pravilnih ujemanj:

Rezultati kviza

Rezultati kviza

0%
0%