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.


Poglejmo si primer:

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 1

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.
ord(s)

vrne kodo edinega znaka niza s

Zgled 2

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 le-to preveri (glej stransko opombo).


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.
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 3

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 4

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.


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

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?

try
range
for
do

Pravilno

Res je! For zanka je najbolj uporabljan konstrukt za zankanje v Pythonu.

Naprej

Napačno

Ne bo držalo! Namig: funkcija range se pogosto uporablja v zankah, vendar ni vrsta zanke; zanke do ne pozna python; try sploh ni zanka!

Naprej

Vprašanje 2

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

Za koliko zanka v zgornji kodi poveča vrednost posameznega elementa seznama?

Preveri

Pravilno

Odlično! Vrednost posameznega elementa se res poveča za 2!

Naprej

Napačno

Ne, ne! V zadnji vrstici kode se skriva pravilen odgovor, kjer vidimo da zanka poveča vrednost zadnjega elementa za 2!

Naprej

Vprašanje 3

V katerem območju vrne elemente range (10)?

od vključno 0 do vključno 9
od vključno 1 do vključno 10
od vključno 0 do vključno 10
od vključno 1 do vključno 9

Pravilno

Tako se odgovarja! Dobimo torej naslednje elemente: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Naprej

Napačno

Še si bo treba pogledati ukaz range! range (10) vrne elemente od vključno 0 do vključno 9!

Naprej

Rezultati kviza

Krajši "problem": 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 problema 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.


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)
0%
0%