Ci, którzy mieli styczność z innymi językami programistycznymi jak np. Java czy C++, mogą się w tym miejscu poczuć zaskoczeni, że w Pythonie blok else występuje także w innych konstrukcjach niż if-else. Jest to jedna z tych rzeczy, która wyróżnia Pythona 🙂

Else w pętlach (for … else, while … else)

Podstawową ideą użycia else w pętli, jest wykonanie jakiejś instrukcji na końcu, po tym jak wykona się cała pętla. Else nie zostanie wykonane, jeśli pętla zostanie przerwana przez polecenie break.

Oto prosty przykładzik:

i=0
while i<10:
   if i==5:
       break
   print(i)
   i+=1
else:
   print("Ten komunikat pojawiłby się, gdyby pętla nie została przerwana")

Output:

>>>
1
2
3
4

Dla pętli for zrobimy, coś bardziej ambitniejszego.

Ćwiczenie:

Chcemy stworzyć prostą funkcję, która będzie nam zwracać listę wszystkich liczb pierwszych z podanego zakresu. Jeśli ktoś nie pamięta, to liczba pierwsza, to taka liczba naturalna większa od 1, która dzieli się tylko przez 1 i przez siebie samą.

  1. Tworzymy pustą listę,w której będziemy umieszczać liczby pierwsze.
  2. Wiemy, że sprawdzana liczba musi być większa od 1, więc mamy warunek if number>1. Pozostałe liczby nie są w ogóle sprawdzane.
  3. W funkcji użyjemy dwóch pętli for. W pierwszej będziemy iterować po liczbach w podanym zakresie, który określiłam za pomocą zmiennych startNumber i endNumber.  
  4. W drugiej pętli szukamy dzielników. Wykluczamy wartość aktualnie sprawdzanej liczby (zmienna number) oraz 1.
  5. Jeśli reszta z dzielenia (modulo) jest równa 0, to znaczy że liczba jest złożona. Przerywamy pętlę, bo nie ma potrzeby szukać następnych dzielników.
  6. Jeśli nie przerwie pętli, oznacza to, że liczba jest liczbą pierwszą i zostanie wykonany blok else.

Moje rozwiązanie:

def primality(startNumber,endNumber):
   prime_numbers=[]
   for number in range(startNumber, endNumber+1):
       if number > 1:
           for x in range (2, number):
               if number%x==0: break
           else:
               prime_numbers.append(number)
   return prime_numbers

A teraz sprawdzimy dla przykładowych liczb:

print(primality(10,20))
print(primality(-5,4))
print(primality(100,1000))

>>>

[11, 13, 17, 19]
[2, 3]
[101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]

Oczywiście można też odwrócić warunek i dać if number%x!=0: break. Wtedy funkcja zwróciłaby listę wszystkich złożonych liczb z podanego zakresu.

Tak właściwie else jest rzadko używany w pętlach, bo po prostu nie ma takiej potrzeby. Poza tym else można zastąpić innymi konstrukcjami. Jednakże warto wiedzieć, że można coś takiego zrobić. Może komuś się przyda. Najważniejsze, żeby program działał 🙂

Try … except razem z else (i opcjonalnie finally)

Blok try-except pozwala nam obsłużyć oczekiwany błąd. Instrukcje zawarte w bloku try zostaną wykonane do momentu pojawienia się błędu. Jeśli błąd się nie pojawi, to zostaną wykonane instrukcje zawarte w else, jeśli go użyliśmy. W przypadku wystąpienia błędu python przechodzi do bloku except. Przy czym możemy użyć więcej niż jednego except dla różnych rodzajów błędów. Jeśli chcemy, aby jakiś fragment kodu został zawsze wykonany, zarówno podczas wystąpienia błędu, jak i w odwrotnej sytuacji, to dodamy finally. Else może występować w samej konstrukcji try-except, jak i try-except-finally.

jakis_string="coś tam"
liczba=77
try:
   print(jakis_string) #wykona się
   zmienna=liczba+jakis_string #nie wykona się, bo nie można dodawać int do str
   print(zmienna)
except TypeError:
   zmienna=str(liczba)+jakis_string
except: #ten blok zostanie wykonany dla błędu innego niż TypeError
   print("Jakiś błąd")
finally:
   print("Na pewno się pojawię. A oto nasza zmienna: ", zmienna)

Wynik jaki otrzymamy:

>>>
coś tam
Na pewno się pojawię. A oto nasza zmienna:  77coś tam

Teraz to samo tylko dodamy else oraz zmienimy trochę nasze zmienne, aby nie wystąpił błąd:

jakas_liczba=100
liczba=77
try:
   zmienna=liczba+jakas_liczba
except TypeError:
   zmienna=str(liczba)+jakas_liczba
except: #ten blok zostanie wykonany dla błędu innego niż TypeError
   print("Jakiś błąd")
else:
   zmienna+=100
finally:
   print("Na pewno się pojawię. A oto nasza zmienna: ", zmienna)

Po uruchomieniu kodu otrzymamy:

>>>
Na pewno się pojawię. A oto nasza zmienna: 277

Użycie klauzuli else może pomóc uniknąć przypadkowego wyłapania wyjątku, który nie został zgłoszony przez kod chroniony w try-except. Ogólnie else ma sprawić, żeby nasz kod był bardziej czytelny i mniej zbugowany. Jednak użycie else tak jak finally jest opcjonalne, więc wszystko zależy od konceptu programisty.