CyberStars

Nested Loops

Știm deja ce face o buclă for. Dar ce se întâmplă dacă punem o buclă în interiorul altei bucle? Asta se numește buclă imbricată și este unul dintre acele lucruri care par confuze la început, dar devin a doua natură odată ce le vezi în acțiune

Să începem simplu. Vrem să afișăm toate combinațiile a două aruncări de zaruri

for zar1 in range(1, 7):
    for zar2 in range(1, 7):
        print(f"{zar1} {zar2}")

Asta va afișa 36 de linii: (1,1), (1,2), ..., (1,6), (2,1), (2,2), ... până la (6,6)

Cum funcționează? Bucla exterioară începe cu zar1 = 1. Apoi bucla interioară rulează complet de la zar2 = 1 până la zar2 = 6. După ce bucla interioară se termină, bucla exterioară trece la zar1 = 2, iar bucla interioară rulează din nou de la zero. Și așa mai departe

Gândește-te ca la un ceas: bucla interioară este acul minutar (merge repede, rotație completă), bucla exterioară este acul orar (se mișcă doar după ce acul minutar termină un ciclu complet)


O utilizare foarte frecventă: afișarea unei tabele de înmulțire

for i in range(1, 6):
    for j in range(1, 6):
        print(f"{i} x {j} = {i * j}")
    print("---")

print("---") este în interiorul buclei exterioare, dar în afara buclei interioare, așa că se afișează după fiecare „rând" de înmulțiri. Fii atent la indentare, contează foarte mult aici


Putem folosi bucle imbricate și cu liste

echipe = ["Sharks", "Bears"]
jucatori = ["Tommy", "Lance", "Cortez"]

for echipa in echipe:
    for jucator in jucatori:
        print(f"{jucator} joaca pentru {echipa}")

Ieșire

Tommy joaca pentru Sharks
Lance joaca pentru Sharks
Cortez joaca pentru Sharks
Tommy joaca pentru Bears
Lance joaca pentru Bears
Cortez joaca pentru Bears

Fiecare jucător este împerecheat cu fiecare echipă. Bucla exterioară alege o echipă, iar bucla interioară parcurge toți jucătorii pentru acea echipă


break în interiorul unei bucle imbricate oprește doar bucla interioară, nu și pe cea exterioară

for i in range(1, 4):
    for j in range(1, 4):
        if j == 2:
            break
        print(f"{i} {j}")

Ieșire

1 1
2 1
3 1

Când j ajunge la 2, break oprește bucla interioară, dar bucla exterioară continuă la următorul i


Afișăm pe aceeași linie cu end=""

Până acum, fiecare print() trecea automat la o linie nouă după ce afișa. Putem schimba asta cu end

print("a", end="")
print("b", end="")
print("c")

Afișează

abc

Normal, cele trei print() ar fi pus a, b și c pe linii separate. Cu end="" îi spunem lui print „nu trece la linie nouă, lasă cursorul aici". Ultimul print("c") nu are end="", așa că după el chiar coborâm pe linia următoare

Asta devine puternic împreună cu buclele imbricate: putem desena o formă rând cu rând

for rand in range(3):
    for stea in range(3):
        print("*", end="")
    print()

Afișează

***
***
***

Hai să urmărim ce se întâmplă:

  • bucla exterioară pornește cu rand = 0
  • bucla interioară afișează * de trei ori, toate pe aceeași linie datorită end="" → ***
  • după bucla interioară, print() singur (gol) coboară pe linia următoare
  • bucla exterioară continuă cu rand = 1, apoi rand = 2, și totul se repetă

Bucla interioară desenează un rând întreg, iar print() de la final coboară pe rândul următor


Misiune: Turnul de Semnal

Construiește un turn de steluțe pentru antena stației. Citește de la utilizator câte rânduri are turnul, apoi afișează un triunghi: primul rând are 1 steluță, al doilea 2, al treilea 3, și tot așa până la ultimul rând

Exemplu

Dacă utilizatorul tastează

5

programul afișează

*
**
***
****
*****