2.13. Ciklusvezérlés

Két kulcsszó változtatja meg a ciklus futását:

  • break – azonnal kilép a ciklusból.

  • continue – kihagyja az aktuális iteráció hátralévő részét, és elindítja a következőt.

Mindkettő a legbelső ciklusra vonatkozik, amelyen belül megjelennek.

2.13.1. break

Használd a break kulcsszót, ha egy feltétel teljesülésekor azonnal le akarod állítani a ciklust. A klasszikus „keress és állj le” minta:

found = None
for item in items:
    if matches(item):
        found = item
        break

if found is not None:
    print("found:", found)

Egy while True: ciklusban a break az, amivel a ciklus véget ér:

while True:
    line = next_line()
    if line == "quit":
        break
    process(line)

2.13.2. continue

Használd a continue kulcsszót, ha ki akarod hagyni a törzs hátralévő részét, és a következő iterációra akarsz ugrani. Hasznos elemek szűréséhez egy cikluson belül:

for n in numbers:
    if n < 0:
        continue            # skip negatives
    print(n)

Ugyanez a hatás megírható egy if blokként a törzs többi része köré. A continue néha érthetőbb, ha a kihagyási feltételt könnyebb előre megfogalmazni, mint a megtartási feltételt.

Egy cikluson belül a continue ugyanazt a szerepet játssza, mint egy korai return egy függvényben: átugorja azokat az eseteket, amelyeket nem kezelsz, és a fő munkát laposan, a külső behúzási szinten tartja. A szűrő-és-feldolgoz ciklus a kanonikus forma:

for item in items:
    if item is None:
        continue
    if not item.is_valid():
        continue
    process(item)

A behúzott process(item) sor a tényleges munka; a fölötte lévő egyes őrfeltételek pontosan megfogalmazzák, mely elemek lesznek kihagyva.

2.13.3. else egy cikluson

Mind a for, mind a while elfogad egy opcionális else blokkot. Ez akkor fut le, amikor a ciklus break nélkül fejeződik be. A leggyakoribb felhasználás egy kereső ciklus, amely tartalék megoldást akar, ha semmit nem talált:

for item in items:
    if matches(item):
        print("found:", item)
        break
else:
    print("no match")

Ha egy break aktiválódik, az else blokk kimarad. A konstrukciót így olvasd: „for X in Y: …; vagy különben, ha sosem léptünk ki, csináld Z-t.”

2.13.4. Gyakori ciklusminták

Néhány minta gyakran felbukkan a valós szkriptekben:

  • Lekérdezgetés (polling) – várakozás, amíg valamilyen feltétel igazzá válik, mielőtt továbblépnél. A törzs a pass utasítást használja, a Python üres műveletét; minden behúzott blokknak legalább egy utasítást tartalmaznia kell, és a pass az, amivel azt mondhatod, hogy „itt ne csinálj semmit”:

    while not ready():
        pass
    proceed()
    
  • Állapotgép – egyetlen while True: ciklus, amely egy állapotváltozó alapján választja ki, mit tegyen. Akkor hasznos, ha a munka tisztán néhány megnevezett fázisra bomlik:

    state = "header"
    for line in lines:
        if state == "header":
            if line.startswith("---"):
                state = "body"
        elif state == "body":
            print(line)
    
  • Felhalmozás – eredmény felépítése egy szekvencián végighaladva:

    total = 0
    for x in samples:
        total += x
    mean = total / len(samples)
    

    Sok felhalmozó ciklusnak van egysoros megfelelője egy beépített függvény segítségével. Nyúlj a beépített függvényhez, amikor van rá megfelelő:

    • sum() – összeadja egy iterálható objektum összes elemét.

    • max() / min() – a legnagyobb vagy a legkisebb elem.

    • any()True, ha legalább egy elem igaz értékű.

    • all()True csak akkor, ha minden elem igaz értékű.

    • sorted() – egy új lista a sorrendbe rakott elemekkel.

    • len() – az elemek száma (ahol az iterálható objektum ismeri a hosszát).

    >>> samples = [3, 1, 4, 1, 5, 9, 2, 6]
    >>> sum(samples)
    31
    >>> sum(samples) / len(samples)        # mean
    3.875
    >>> max(samples)
    9
    >>> min(samples)
    1
    >>> sorted(samples)
    [1, 1, 2, 3, 4, 5, 6, 9]
    >>> any([False, False, True])
    True
    >>> all([True, True, False])
    False
    

    A beépített változat rövidebb, érthetőbb és általában gyorsabb, mint ugyanazt a ciklust kézzel megírni.