For petlja

Ova vrsta petlje vrši iteracije na osnovu vrednosti koje uzima iz listа (nizovа), stringovа i rečnikа. Ovaj način iteracije čini for petlju pogodnijom za onaj deo koda koji želimo da se dogodi određen broj puta. Pogledajmo sada ovaj jednostavan primer.

  
niz= [1, 3, 5, 7]

for x in niz:
    print (x),
            
Kopiraj

Kao što bismo mogli da očekujemo izlaz ovog programa je >> 1 3 5 7. Pre ulaska u prvu iteraciju for petlja proverava postojanje prvog elementa u promenljivoj niz i ukoliko on postoji, dodeljuje promenljivoj x vrednost tog prvog elementa. U drugom krugu proverava postojanje drugog člana niza i dodeljuje x-u njegovu vrednost. Ovaj proces se nastavlja sve dok ima elemenata u listi, nakon čega se izlazi iz petlje.

Uporedimo sada dva programa sa istim ishodom, od kojih jedan koristi while a drugi for petlju. Koristimo pomoćnu range() funkciju koja kreira privremenu listu prirodnih brojeva u opsegu od 0 do prosleđene vrednosti umanjene za 1

  
broj = 1
while broj <= 100:
    if broj%5==0:
        print (broj),
    broj = broj +1
				
Kopiraj
  
				
for broj in range(100): 
    if (broj+1)%5==0: 
        print (broj+1),

				
Kopiraj

Izlaz oba programa je isti >> 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 Može se primetiti da je while verzija petlje duža dva reda, ali je lakša za čitanje. Specifični zahtev je taj koji čini ovu for petlju manje čitljivom. Kada bismo dozvolili ispisivanje nule kao broja deljivog sa 5, onda bismo mogli da uklonimo pomeraj promenljive „broj“ za 1. Međutim onda bi nam se javio drugi problem gde nam se ne bi ispisao broj 100, jer range() funkcija ne uzima graničnu vrednost. Najbolje poboljšanje koda bi bilo proširivanje range() funkcije za dodatni parametar koji označava početnu vrednost.

  
for broj in range(1,101): 
    if broj%5==0: 
        print (broj),

            
Kopiraj

Treba obratiti pažnju i na čitljivost koda, jer u svakom programu ima mesta za unapredjenje, a čitljivost olakšava kasnije ispravke.

Zadatak : Koristeći treći argument funkcije range() napraviti program koji ispisuje prvih 100 brojeva deljivih sa 7, bez korišćenja if naredbe.


For/Else i Break

For petlja takođe ima opcionu else granu koja se izvršava pri normalnom izlazu iz petlje. Osim toga možemo koristiti i break naredbu, pri čijem izvršavanju se preskače else grana.

Analizirajmo sada modifikovanu funkciju od ranijeg primera sa bojama koja je proveravala da li se reč nalazi u rečniku.

  
boje = {0:"crvena",1:"zelena",2:"plava", 3:"zuta",4:"roze",5:"ljubicasta",
6:"braon",7:"crna",8:"bela",9:"teget",10:"bez",11:"bordo",12:"ciklama"}

def proveri(boje,trazena_boja):
    for kljuc in boje:
        if boje[kljuc]==trazena_boja:
            return True
    else: return False

        
print (proveri(boje,"crvena"))
print (proveri(boje,"mangeta"))

            
Kopiraj

Pri iteraciji kroz rečnike for petlja uzima ključeve umesto vrednosti. Treba napomenuti da ne možemo biti sigurni kojim redosledom for petlja uzima ključeve, za razliku od prolaska kroz listu kod koje se elementi biraju redom.

Ova funkcija je kraća i jasnija od prethodne verzije sa while petljom. Još važnije od čitljivosti je povećana primenljivost: sada nismo ograničeni tipom ključeva u rečniku boje. Možemo ih promeniti da budu bilo koji brojevi, ili stringovi, pa čak i da dodamo i novu boju u rečnik, bez potrebe za izmenom same funkcije. Pri pisanju funkcija treba težiti da je što manje zavisna od ulaznih parametara, naročito ako to ne utiče na čitljivost ili efikasnost.

Pošto for petlja uzima vrednosti iz konačne liste obično ima i konačan broj iteracija. Međutim ako se lista iz koje for petlja uzima brojeve stalno uvećava npr. pomoću funkcije .append() dobijamo beskonačnu petlju. Evo jednog takvog primera koji pravi listu ispunjenu beskonačnim brojem jedinica.

  
#Oprez, beskonačna petlja
x=[1]
for i in x:
    x.append(1)
            
Kopiraj

Ovakve vrste beskonačnih petlji nemaju neku naročitu primenu, ali se treba upoznati sa njima kako bi se smanjila mogućnost greške pri pisanju programa


Enumerate

Šta ako želimo da se zajedno sa vrednostima u listi, stringu ili rečniku učitavaju i indeksi odnosno redni brojevi tih elemenata u listi. Pajton ima funkciju enumerate koja nam ovo obezbeđuje. Umesto jedne promenljive za upis for petlje imamo dve razdvojene zarezom. U prvoj se učitava trenutni indeks a u drugoj vrednost koja odgovara tom indeksu. Pogledajmo primer koji ilustruje ovu funkciju:

  
for i,slovo in enumerate("Na Drini cuprija"):
    print (str(i)+ " "+slovo)
            
Kopiraj

Pogledajmo sada još jedan primer programa koji implementira korišćenje enumerate. Korisnik unosi redom koja su mu najomiljenija jela, a zatim se ta jela ispisuju zajedno sa gradacijom.

  
jelo = [] 
while(True): #Beskonacna petlja, prekida se samo ako se pokrene break
    rec=input("Unesite jelo ili 'kraj liste' za prekid programa")
    if rec=="kraj liste" :
        break
    jelo.append(rec) #dodajemo rec u listu ukoliko nije 'kraj liste'
    
for i,v in enumerate(jelo):
    """Da bismo dobili zeljeni ispis moramo da dodamo 1 na enumerisane 
brojevi kao i tacku iza broja da bi bio redni"""
    print "Tvoj "+str(i+1)+". "+"izbor je " + v
            
Kopiraj

U ovom slučaju beskonačna petlja nam je olakšala implementaciju. Da smo proveravali u uslovu while petlje da li je rec!=“kraj liste“ onda bismo na listu jelo dodali nepotrebno tu reč, pa bi to iziskivalo dodatnu if naredbu. Tada bismo, međutim imali dve iste provere, što je manje efikasno i zbunjujuće.

Na početku ovog odeljka pomenuto je da je način na koji for petlja uzima ključeve iz rečnika nepredvidiv. Međutim sada smo pomoću enumerate funkcije u mogućnosti da za konkretan rečnik „zapamtimo„ redosled kojim for petlja uzima ključeve. Pa je sada redosled, iako još uvek nepredvidiv, izračunljiv.



Ugnježdene petlje

Jedna ili više petlji mogu da se nalaze ne samo u funkcijama već i u drugim petljama, i ovaj pojam nazivamo ugnježdenim petljama. Pogledajmo odmah jedan primer ugnježdene petlje koja ispisuje pravougaonik ispunjen zvezdicama na izlaz.

  
for i in range(6): 	# petlja koja ispisuje redove
    for j in range(6): # ispisuje zvezdice u jednom redu
        print ('*'),
    print ("")# kraj reda, još uvek unutar spoljnje petlje
            
Kopiraj

Pri analiziranju ugnježdenih petlji često je lakše da se krene od unutrašnje petlje. U našem slučaju unutrašnja petlja ispisuje u istom redu 6 zvezdica, dok spoljašnja petlja ispisuje 6 takvih redova. Postoji i elegantnije rešenje sa istim izlazom.

  
for i in range(6):    
    print '* '*6
            
Kopiraj

Zadatak: Napisati program koji na izlaz ispisuje pravougli trougao sa osnovom od 5 zvezdica, koristeći oba prethodna načina. Za pomoć pogledati dodatak.