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.
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ă:
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:
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:
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ă:
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.