2.12. Loopar

En loop kör samma kodblock upprepade gånger. Python har två former: while, som fortsätter så länge ett villkor förblir sant, och for, som går igenom objekten i en sekvens.

Flödesscheman sida vid sida. while: testa villkoret, kör kroppen om sant, upprepa. for: ta nästa objekt från den itererbara, kör kroppen, upprepa tills den är slut.

while fortsätter att testa ett villkor; for går igenom en sekvens tills den är slut.

2.12.1. while-loopar

En while-loop testar sitt villkor före varje iteration och kör kroppen tills testet blir falskt:

count = 0
while count < 5:
    print(count)
    count += 1

Utdata:

0
1
2
3
4

Om villkoret är sant från början och aldrig blir falskt körs loopen för evigt. while True: är det vanliga idiomet för en huvudloop, som avslutas uttryckligen med break:

while True:
    step()
    if done():
        break

2.12.2. for-loopar

En for-loop går igenom objekten i en itererbar – en lista, tupel, sträng, bytes, dict eller något annat som stöder iteration:

for fruit in ["apple", "banana", "cherry"]:
    print(fruit)

Utdata:

apple
banana
cherry

Samma form fungerar på en sträng, där varje objekt är en sträng med ett tecken:

for letter in "OpenMV":
    print(letter)

Utdata:

O
p
e
n
M
V

Att iterera över en dict direkt ger dess nycklar, i insättningsordning:

for key in {"a": 1, "b": 2}:
    print(key)

Utdata:

a
b

Varje varv binder loopvariabeln (fruit, letter, key) till nästa objekt. När loopen avslutas behåller variabeln värdet från den sista iterationen.

2.12.3. range

För loopar över ett numeriskt intervall, använd range():

  • range(stop) – 0, 1, …, stop - 1.

  • range(start, stop) – start, start + 1, …, stop - 1.

  • range(start, stop, step) – med ett anpassat steg (negativa värden räknar nedåt).

for i in range(5):           # 0, 1, 2, 3, 4
    print(i)

for i in range(2, 8, 2):     # 2, 4, 6
    print(i)

for i in range(10, 0, -1):   # 10, 9, ..., 1
    print(i)

range() producerar värden lat – den bygger inte en lista i minnet. För att få en faktisk list, omslut den: list(range(10)).

2.12.4. enumerate

När loopen behöver både indexet och objektet ger enumerate() par av (index, item):

for i, name in enumerate(["a", "b", "c"]):
    print(i, name)
# 0 a
# 1 b
# 2 c

Starta indexet på något annat än noll genom att skicka ett andra argument: enumerate(items, start=1).

2.12.5. zip

För att gå igenom två (eller flera) itererbara i takt, använd zip(). Den ger en tupel per position och stoppar vid den kortaste indatan:

names  = ["alice", "bob", "carol"]
scores = [88, 92, 70]

for name, score in zip(names, scores):
    print(name, score)

Utdata:

alice 88
bob 92
carol 70

2.12.6. Inline-tilldelning med :=

Valross-operatorn := är en tilldelning som också är ett uttryck. Den binder ett namn och evalueras till samma värde samtidigt. I en while-loop komprimerar detta det vanliga mönstret ”läs, kontrollera, kropp” till en rad:

# without walrus
value = next_value()
while value is not None:
    process(value)
    value = next_value()

# with walrus
while (value := next_value()) is not None:
    process(value)

De två formerna gör samma sak. Använd := när dubbleringen av tilldelningen verkligen skadar läsbarheten; använd den inte bara för att vara smart. Parenteserna krävs i de flesta positioner för att hålla uttrycket otvetydigt.