Per què repetim instruccions?
Un bucle executa un bloc de codi repetidament mentre es compleixi (o per a cada element d'una seqüència) una condició. Evita haver d'escriure la mateixa instrucció moltes vegades i permet recórrer llistes, comptar, o esperar un esdeveniment.
while mentre la condició sigui certa
Comprova la condició abans de cada volta. Si és falsa des del principi, el cos no s'executa mai. En Python, el cos es marca amb indentació (espais), no amb claus.
Sintaxi
while condició:
# cos: s'executa mentre condició sigui certa
Exemple
i = 1
while i <= 5:
print(i)
i += 1
S'imprimeixen els nombres 1 a 5. Cada volta: es comprova i <= 5, s'executa el cos, i s'incrementa i manualment — si oblidéssim l'i += 1, el bucle no acabaria mai.
for recorrent una seqüència
Un for en Python recorre els elements d'una seqüència. Amb range(inici, final, pas) es genera una seqüència de nombres sense incloure el valor final.
Sintaxi
for variable in seqüència:
# cos
Exemple
for i in range(1, 6):
print(i)
range(1, 6) genera 1, 2, 3, 4, 5 — el 6 no s'inclou mai. A cada volta, i pren el següent valor del rang; quan s'exhaureix, el bucle acaba tot sol, sense necessitat d'incrementar res a mà.
Control del flux dins un bucle
De vegades cal sortir abans d'hora, saltar-nos una volta concreta, o simplement no fer res.
break
Talla el bucle immediatament: no es torna a comprovar la condició ni el rang, s'ix directament del bucle.
for i in range(1, 11):
if i == 4:
break
print(i)
# imprimeix: 1 2 3
continue
Salta directament a la següent volta, sense executar la resta del cos d'aquesta volta.
for i in range(1, 6):
if i == 3:
continue
print(i)
# imprimeix: 1 2 4 5 (el 3 no s'arriba a imprimir)
pass
No fa absolutament res. És un marcador de lloc buit: s'utilitza quan la sintaxi exigeix un bloc (per exemple dins un if) però encara no hi vols posar cap instrucció. A diferència de continue, pass no salta res: l'execució simplement continua a la línia següent com si aquell bloc no hi fos.
for i in range(1, 6):
if i == 3:
pass
print(i)
# imprimeix: 1 2 3 4 5 (el 3 SÍ s'imprimeix: pass no salta res)
Mira el bucle executar-se pas a pas
Tria una variant i avança pas a pas (o deixa-ho en reproducció automàtica) per veure com evolucionen les variables i la sortida per terminal.
Codi
Variables
| Nom | Valor |
|---|
Terminal
Problemes per resoldre
Sense solució ni comprovació automàtica: escriu el programa, executa'l (python3 programa.py) i prova'l amb els exemples. Amb variables, condicionals i bucles en tens prou. Les pistes són plegades perquè les obris només si les necessites.
1. Suma d'una progressió aritmètica for
Una progressió aritmètica té com a terme general a(n) = a·n + b. Demana a i b (nombres decimals) i n (enter), i calcula la suma dels n primers termes sumant-los un a un. Després comprova el resultat calculant-lo també amb la fórmula (a1 + an) · n / 2, on a1 és el primer terme i an l'últim.
a: 2 b: 1 n: 5 Suma dels 5 primers termes: 35.00 Amb la fórmula: 35.00
Pistes
Els termes són 3, 5, 7, 9 i 11, i sumen 35. Necessites un acumulador suma que comenci a 0 i un for ct in range(1, n + 1): (recorda que range no inclou el final); a cada volta hi afegeixes a*ct + b.
Llegeix a i b amb float(input(...)) i n amb int(input(...)). El primer terme és a*1 + b i l'últim a*n + b. Amb una f-string com f"{suma:.2f}" obtens els dos decimals.
2. Una dada vàlida while True + break
Demana una nota entre 0 i 10 (tots dos inclosos). Si l'usuari escriu un valor fora d'aquest rang, mostra un missatge d'error i torna a demanar-la, tantes vegades com calgui. Quan la nota sigui correcta, mostra-la.
Nota (0-10): 12 Valor fora de rang. Nota (0-10): -3 Valor fora de rang. Nota (0-10): 7 Nota acceptada: 7
Pistes
Python no té do-while: la nota s'ha de demanar almenys un cop, i això es fa amb while True: i un break quan el valor és correcte.
Comprova el rang amb la comparació encadenada 0 <= nota <= 10. El missatge d'error només s'ha de mostrar quan el valor és incorrecte.
3. Multiplicació russa while True + break
L'algorisme rus per multiplicar escriu a i b en dues columnes. A cada fila, a es divideix entre 2 (divisió entera) i b es multiplica per 2, fins que a arriba a 0. La suma dels valors de b de les files on a és senar és el producte a·b. Escriu un programa que ho calculi així, sense fer a*b.
Introdueix a i b: 46 43
46 x 43 = 1978
Pistes
Per a 46 i 43 les files són:
a b 46 43 23 86 ← a és senar: se suma 86 11 172 ← senar: se suma 5 344 ← senar: se suma 2 688 1 1376 ← senar: se suma
I 86 + 172 + 344 + 1376 = 1978.
Com que no hi ha do-while, fes servir while True: i surt amb break quan a arribi a 0 (al final de cada volta). Treballa amb còpies x i y si vols escriure a i b originals. Divisió entera: //. Pots fer x, y = x // 2, y * 2 en una sola línia. Per llegir dos valors, demana'ls amb dos input() separats.
4. Decimal a binari while
Demana un nombre natural més petit que 256 i escriu-ne la representació en binari fent divisions successives per 2 i quedant-te amb les restes. Si el nombre no és vàlid, torna a demanar-lo.
Nombre (0-255): 100
100 en binari és 1100100
Pistes
Les restes surten de dreta a esquerra: 100%2 = 0, 50%2 = 0, 25%2 = 1, 12%2 = 0... La primera que surt és el bit menys significatiu.
En Python pots construir el resultat com una cadena: comença amb bin = "" i a cada volta posa la resta al davant, bin = str(resta) + bin.
Comprova que el 0 també funciona: el bucle no s'executa cap cop i la cadena queda buida, així que caldrà tractar-lo a part. Per demanar el nombre fins que sigui vàlid, reutilitza la idea de l'exercici 2.
5. Nombre primer while
Demana un enter n i digues si és primer. Un nombre és primer si només és divisible entre 1 i entre ell mateix; el 0 i l'1 no ho són.
Nombre: 17 17 és primer Nombre: 91 91 no és primer Nombre: 1 1 no és primer
Pistes
Prova els divisors 2, 3, 4... i para en trobar el primer que divideixi n (n % divisor == 0): no cal mirar-los tots.
N'hi ha prou de provar-los mentre divisor*divisor <= n (si n té un divisor més gran que la seva arrel, en té també un de més petit). Així no cal cap arrel quadrada ni import math.
Una variable booleana primer que passa a False quan trobes un divisor et deixa sortir amb la condició del while. Comença-la a False si n < 2.
6. MCD de tres nombres while
L'algorisme d'Euclides calcula el màxim comú divisor de m i n: mentre n no sigui 0, es substitueix (m, n) per (n, resta de m entre n); quan n és 0, el MCD és m. Escriu un programa que llegeixi tres enters positius i en calculi el MCD, sabent que MCD(a, b, c) = MCD(MCD(a, b), c).
a: 120 b: 140 c: 210 MCD(120, 140, 210) = 10
Pistes
Els passos són MCD(120, 140) = 20 i després MCD(20, 210) = 10.
El cos del bucle es pot escriure en una sola línia amb assignació múltiple: m, n = n, m % n. Calcula primer el MCD d'a i b i guarda'l; després aplica el mateix bucle amb aquest resultat i c. Treballa amb còpies si vols escriure a, b i c al final.
7. L'algorisme 3n+1 while
Parteix d'un enter n ≥ 1 i repeteix: escriu n; si n val 1, acaba; si n és senar, substitueix-lo per 3n+1; si és parell, per n/2. Escriu tots els valors (el «cicle» de n) en una sola línia i, al final, la longitud del cicle (quants valors has escrit, comptant el primer i l'1).
Nombre: 22 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 Longitud del cicle: 16 Nombre: 8 8 4 2 1 Longitud del cicle: 4
Pistes
No saps quantes voltes farà el bucle, per això un while (que s'acaba quan n val 1) hi encaixa millor que un for.
Per escriure en una sola línia fes servir print(n, end=" "), i un print() buit al final per saltar de línia. Divisió entera per 2: n // 2. Un comptador que comenci a 1 et dona la longitud. Prova nombres de la forma 2n (64, 1024...): tenen cicles molt curts.
8. Nombres «XX» bucles encaixats
Diem que un enter és «XX» si tots els seus divisors, excepte ell mateix i l'1, són nombres primers. Demana un enter positiu N i escriu tots els nombres «XX» entre 0 i N (tots dos exclosos), separats per espais.
N: 21
1 2 3 4 5 6 7 9 10 11 13 14 15 17 19
Pistes
El 8 no és «XX» perquè és divisible entre 4, que no és primer. El 6 sí que ho és: els seus divisors 2 i 3 són primers. L'1 no té cap divisor per comprovar, així que hi entra.
Tres bucles encaixats: el de fora recorre els candidats i d'1 a N-1 (range(1, N)); el del mig recorre els possibles divisors d de 2 a i-1 i mira si i % d == 0; el de dins comprova si aquest divisor és primer (com a l'exercici 5).
Una variable booleana xx que comença a True i passa a False quan trobes un divisor que no és primer. Escrius i només si, en acabar, xx segueix a True.
Exercicis d'autoavaluació
Cada exercici es genera amb valors nous a l'atzar. Llegeix el codi, pensa quina serà la sortida per terminal i comprova-ho.
Quina serà la sortida per terminal d'aquest programa?