Python 3 per a no programadors/Bucles for

I aquí hi ha el nou exercici per teclejar en aquest capítol:

unadeu = range(1, 11)
for contador in unadeu:
    print(contador)

i el resultat sempre present:

1
2
3
4
5
6
7
8
9
10

El resultat sembla terriblement familiar però el codi del programa sembla diferent. La primera línia fa servir la funció range. La funció range fa servir dos arguments així range(començament, final). "començament" és el primer nombre que es produeix. final és una unitat més gran que l'últim nombre. Fixeu-vos que aquest programa es podria haver fet d'una manera més curta:

for contador in range(1, 11):
    print(contador)

La funció range és un iterable. Això es pot transformar en una llista amb la funció list. Aquí hi ha alguns exemples per mostrar que passa amb el comandament range:

>>> range(1, 10)
range(1, 10)
>>> list(range(1, 10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(-32, -20))
[-32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21]
>>> list(range(5,21))
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
>>> list(range(5))
[0, 1, 2, 3, 4]
>>> list(range(21, 5))
[]

La següent línia for contador in uadeu: fa servir l'estructura de control for. Una estructura de control for te l'aspecte de for variable in llista:. llista passa per tot els elements començant amb el primer element de la llista i acabant amb l'últim. A mesura que for passa per cada element de la llista el posa a la variable. Això permet que variable es faci servir cada una de les successives vegades que s'executa el bucle for. Aquí hi ha un altre exemple (no teniu que teclejar-lo) de demostració:

llistademo = ['vida', 42, 'l\'univers', 6, 'i', 7, 'tot']
for objecte in llistademo:
    print("L'objecte actual és:",objecte)

El resultat és:

L'objecte actual és: vida
L'objecte actual és: 42
L'objecte actual és: l'univers
L'objecte actual és: 6
L'objecte actual és: i
L'objecte actual és: 7
L'objecte actual és: tot

Fixeu-vos com el bucle for ressegueix cada element de la llista i estableix el valor de objecte igual al de cada element de la llista. Així, perquè va be el for? El primer ús és per passar a través de tots els elements d'una llista i fer quelcom amb cada un d'ells. Aquí hi ha una forma ràpida per sumar tots els elements:

llista = [2, 4, 6, 8]
suma = 0
for nombre in llista:
    suma = suma + nombre

print("La suma és:", suma)

on el resultat és simplement:

La suma és: 20

O podríeu escriure un programa per trobar si hi ha alguns elements duplicats a la llista tal com fa aquest programa:

llista = [4, 5, 7, 8, 9, 1, 0, 7, 10]
llista.sort()
previ = llista[0]
del llista[0]
for element in llista:
    if previ == element:
        print("S'ha trobat un duplicat de", previ)
    previ = element

i dóna:

S'hatrobat un duplicat de 7

Be, així com funciona? Aquí hi ha una versió especial de depuració per ajudar-vos a entendre-ho (no cal que ho teclegeu):

l = [4, 5, 7, 8, 9, 1, 0, 7, 10]
print("l = [4, 5, 7, 8, 9, 1, 0, 7, 10]", "\t\tl:", l)
l.sort()
print("l.sort()", "\t\tl:", l)
previ = l[0]
print("previ = l[0]", "\t\tprev:", previ)
del l[0]
print("del l[0]", "\t\tl:", l)
for objecte in l:
    if previ == objecte:
        print("S'ha trobat duplicat de", previ)
    print("if previ == objecte:", "\t\tprevi:", previ, "\tobjecte:", objecte)
    previ = objecte
    print("previ = objecte", "\t\tprevi:", previ, "\tobjecte:", objecte)

essent el resultat:

l = [4, 5, 7, 8, 9, 1, 0, 7, 10]        l: [4, 5, 7, 8, 9, 1, 0, 7, 10]
l.sort()                l: [0, 1, 4, 5, 7, 7, 8, 9, 10]
previ = l[0]             previ: 0
del l[0]                l: [1, 4, 5, 7, 7, 8, 9, 10]
if previ == objecte:        previ: 0         objecte: 1
previ = item             previ: 1         objecte: 1
if previ == objecte:        previ: 1         objecte: 4
previ = item             previ: 4         objecte: 4
if previ == objecte:        previ: 4         objecte: 5
previ = item             previ: 5         objecte: 5
if previ == objecte:        previ: 5         objecte: 7
previ = item             previ: 7         objecte: 7
S'ha trobat duplicat de 7
if previ == objecte:        previ: 7         objecte: 7
previ = item             previ: 7         objecte: 7
if previ == objecte:        previ: 7         objecte: 8
previ = item             previ: 8         objecte: 8
if previ == objecte:        previ: 8         objecte: 9
previ = item             previ: 9         objecte: 9
if previ == objecte:        previ: 9         objecte: 10
previ = item             previ: 10        objecte: 10

La raó de posar tantes instruccions print en el codi és perquè pugeu veure el que està passant en cada línia. (Per cert, si no podeu imaginar per què no està funcionant un programa, intenteu inserir motes instruccions print en llocs d'on vulgueu saber què està passant.) Primer el programa comença amb una llista antiga avorrida. Després el programa ordena la llista. Aquesta és de manera perquè alguns duplicats es posin l'un al costat de l'altre. Llavors el programa inicialitza la variable "previ". Després el primer element de la llista se suprimeix de manera que no es cregui incorrectament que el primer element és un duplicat. Després s'entre en un bucle for. Cada element de la llista es comprova per veure si és el mateix que el previ. Si és es trobava un duplicat. Llavors el valor de previ es canvia de manera que la propera vegada que el bucle for s'executa completament previ és l'element previ al actual. Efectivament, es troba que el 7 és un duplicat. (Fixeu-vos com es fa servir \t\t per escriure un tabulador.)

L'altra forma de fer servir el bucle for és per fer quelcom un determinat nombre de vegades. Aquí hi ha un codi per escriure els primers 9 nombres de la sèrie de Fibonacci:

a = 1
b = 1
for c in range(1, 10):
    print(a,end=" ")
    n = a + b
    a = b
    b = n

Amb el sorprenent resultat:

1 1 2 3 5 8 13 21 34

Tot el que es pot fer amb els bucles for també es pot fer amb bucles while però els bucles for subministren una forma fàcil de passar per tots els elements d'una llista o de fer quelcom un determinat nombre de vegades.