Conținut curs
Gestionarea erorilor și excepțiilor
0/1
Python Intermediar
Despre lecție

Obiective:

  • Introducerea conceptului de iteratori în Python
  • Utilizarea metodei __iter__ și a metodei __next__
  • Crearea de obiecte iterabile personalizate
  • Exemple practice și aplicații ale iteratorilor și metodei __iter__

Introducere: Iteratori în Python

Iteratorii sunt obiecte care permit parcurgerea elementelor unei colecții, cum ar fi o listă sau un dicționar, într-un mod secvențial. Un iterator trebuie să implementeze două metode, __iter__() și __next__(). Metoda __iter__ ar trebui să returneze obiectul iterator, iar metoda __next__ ar trebui să returneze următorul element din colecție.

Python oferă suport implicit pentru iteratori în majoritatea colecțiilor sale predefinite, cum ar fi liste, tuple, seturi și dicționare. Putem folosi iteratorii într-un for sau cu funcția next().

Metoda __iter__ și metoda __next__

Metoda __iter__() este apelată atunci când un obiect este folosit într-un context iterabil, cum ar fi un for. Această metodă trebuie să returneze obiectul iterator. În majoritatea cazurilor, obiectul iterator este chiar obiectul care implementează metoda __iter__.

Metoda __next__() este apelată pentru a obține următorul element din colecție. Dacă nu mai există niciun element, metoda ar trebui să ridice excepția StopIteration.

python
class NumerePare:
    def __init__(self, max_val):
        self.max_val = max_val
        self.curent = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.curent >= self.max_val:
            raise StopIteration
        else:
            self.curent += 2
            return self.curent - 2

Crearea de obiecte iterabile personalizate

Pentru a crea un obiect iterabil personalizat, trebuie să implementăm metodele __iter__ și __next__. De exemplu, să creăm o clasă care generează numere pare până la o valoare maximă:

python
class NumerePare:
    def __init__(self, max_val):
        self.max_val = max_val
        self.curent = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.curent >= self.max_val:
            raise StopIteration
        else:
            self.curent += 2
            return self.curent - 2

# Folosirea obiectului iterabil personalizat
numere_pare = NumerePare(10)
for numar in numere_pare:
    print(numar)  # Output: 0 2 4 6 8

Exemple practice și aplicații ale iteratorilor și metodei __iter__

1. Generarea numerelor Fibonacci

Putem crea un obiect iterabil care generează primele n numere Fibonacci:

python
class Fibonacci:
    def __init__(self, n):
        self.n = n
        self.count = 0
        self.a, self.b = 0, 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.count >= self.n:
            raise StopIteration
        else:
            self.count += 1
            self.a, self.b = self.b, self.a + self.b
            return self.a

fibonacci = Fibonacci(10)
for numar in fibonacci:
    print(numar, end=" ")  # Output: 1 1 2 3 5 8 13 21 34 55

2. Parcurgerea elementelor dintr-un dicționar

Un dicționar este iterabil implicit prin cheile sale, dar putem folosi metoda items() pentru a itera peste perechile cheie-valoare:

python
dictionar = {'a': 1, 'b': 2, 'c': 3
for cheie, valoare in dictionar.items():
    print(f"{cheie}: {valoare}")

# Output:
# a: 1
# b: 2
# c: 3

3. Implementarea unei clase pentru parcurgerea unei liste în ordine inversă

Putem crea o clasă care acceptă o listă și permite parcurgerea elementelor în ordine inversă:

python
class ListaInversa:
    def __init__(self, lista):
        self.lista = lista

    def __iter__(self):
        self.index = len(self.lista)
        return self

    def __next__(self):
        if self.index <= 0:
            raise StopIteration
        else:
            self.index -= 1
            return self.lista[self.index]

lista = [1, 2, 3, 4, 5]
lista_inversa = ListaInversa(lista)

for element in lista_inversa:
    print(element, end=" ")  # Output: 5 4 3 2 1

În această lecție, am învățat despre iteratori în Python și cum să utilizăm metoda __iter__ pentru a crea obiecte iterabile personalizate. Am văzut și cum să implementăm metoda __next__ pentru a controla comportamentul de iterație. În final, am explorat exemple practice și aplicații ale iteratorilor și metodei __iter__, care pot fi extrem de utile în procesarea și manipularea diferitelor tipuri de colecții de date.