Pchełki Python: zaprzeczenie pętli

Pythona używam rzadko. Prawdę powiedziawszy nigdy jeszcze nie miałem okazji napisać linijki kodu w tym języku dla któregokolwiek z moich pracodawców. Czasem zerknę w jakiś kod źródłowy, żeby „być na bieżąco”. Czasem dla hecy napiszę parę prościutkich linijek. Póki co więcej mi nie potrzeba.

Python jest zwarty, elegancki, niezwykle popularny, wymusza poprawne formatowanie kodu (wcięcia!) oraz – co najważniejsze – jest aktywnie rozwijany. Ma też oczywiście wady: jest wysokopoziomowy (a więc względnie wolny), mało popularny na platformach mobilnych (Android, IOS), jest późno typowany (typy zmienych i wyrażeń są ustalane na etapie wykonania programu, a nie kompilacji) przez to uczy początkujących programistów złych nawyków, a także ułatwia popełnianie błędów związanych z rzutowaniem typów.

Jednak lubię ten język i od czasu do czasu przeglądam sobie różne materiały on-line, z czystej ciekawości.

Niedawno trafiłem na perełkę, która wprawiła mój mózguł (nie łudzę się, że mam więcej niż jeden) w lekkie zdziwienie.

Otóż okazuje się, że operatora ELSE można w Pythonie używać nie tylko jako uzupełnienia bloku IF, ale także jako dodatku do pętli FOR.

Żeby było śmieszniej (ale nie jest), działanie tego operatora w przypadku pętli FOR jest zgoła przeciwne do tego, co podpowiada nam intuicja. O ile bowiem – i jest to prawdą nie tylko w Pythonie, ale w większości języków programowania implementujących ten paradygmat – blok IF-ELSE oznacza „Wykonaj ten kawałek kodu pod takim to a takim warunkiem, w przeciwnym razie wykonaj tamten kawałek”, o tyle w Pythonie blok FOR-ELSE oznacza: „Wykonaj pętlę FOR, a potem, o ile pętla zakończyła się bez używania operatora BREAK – wykonaj również ten kawałek po ELSE”.

Innymi słowy – zamieszanie.

Jednak użyteczność tej konstrukcji, chociaż jej składnia może nieco razić, jest niezaprzeczalna. Weźmy taki przykład:

from math import sqrt, ceil
 
 
def is_prime(n: int):
    if(n < 3):
        return(n == 2)
 
    if(n % 2 == 0):
        return(False)
    else:
        for d in range(3, ceil(sqrt(n)), 2):
            if(n % d == 0):
                break
        else:
            return(True)
    return(False)
Funkcja is_prime to naiwna implementacja algorytmu sprawdzającego pierwszość liczby. Najpierw „obsługuje” przypadki szczególne (0, 1, 2), potem parzystość, a na koniec zabiera się za sprawdzanie, czy liczba dzieli się przez którąkolwiek z liczb nieparzystych począwszy od trójki aż do pierwiastka ze sprawdzanej liczby (zaokrąglonego w górę do pełnej całości).

Przy okazji: tutaj opisałem algorytm o wiele potężniejszy.

Najbardziej interesujący jest tutaj ten kawałek:

        for d in range(3, ceil(sqrt(n)), 2):
            if(n % d == 0):
                break
        else:
            return(True)
    return(False)
Pętla for wykonuje się dopóty, dopóki nieparzysta liczba d (dzielnik) nie przekroczy pierwiastka z liczby sprawdzanej (zaokrąglonego w górę), chyba że natrafimy na podzielnik – wtedy kończymy pętlę for za pomocą break. Blok else natomiast wykona się *wyłącznie* wtedy, jeżeli zakończenie pętli for nastąpiło w sposób „naturalny” (a więc jeżeli zostały wykorzystane wszystkie dostępne wartości zmiennej d i nie natrafiono na operator break).
Gdybyśmy nie mieli do dyspozycji owego else (bądź czegoś analogicznego), wówczas musielibyśmy uciekać się do tworzenia flagi (dodatkowej zmiennej), która mówiłaby nam, czy wyjście z pętli nastąpiło w wyniku znalezienia podzielnika, czy wyczerpania wiaderka z podzielnikami.

Nudne, prawda?

5
Dodaj komentarz

avatar
3 Comment threads
2 Thread replies
5 Followers
 
Most reacted comment
Hottest comment thread
5 Comment authors
StefekHokoxpilButter40i4 Recent comment authors
  Subscribe  
najnowszy najstarszy oceniany
Powiadom o
40i4
Gość

Nudne, nudne, ale doczytałem do końca, oczywiście pomijając treść kodu 🙂
A z tym konkursem to niezły numer. Zabrakło propagacji (wykop.pl lub inne place zabaw, tylko nie wiem, czy wiedzieliby o co chodzi…)

Butter
Gość
Butter

wygląda na równie użyteczna jak czekoladowy czajnik.

Hoko
Gość

Przecie są czekoladowe. A przynajmniej był…
https://www.bbc.co.uk/news/uk-england-york-north-yorkshire-29126161

%d bloggers like this: