5.2 Οι επαναλήπτες (iterators) στην Python

Οι επαναλήπτες (iterators) στην Python είναι αντικείμενα που επιτρέπουν τη διάσχιση μιας σειράς τιμών. Αναφέρονται ως αντικείμενα που υλοποιούν το πρωτόκολλο επαναλήπτη, το οποίο αποτελείται από τις μεθόδους __iter__() και __next__().

Οι επαναλήπτες έχουν πολλές εφαρμογές, για παράδειγμα, όταν θέλουμε να επεξεργαστούμε τα στοιχεία μιας λίστας ή άλλων συλλογών δεδομένων. Με τη χρήση ενός επαναλήπτη, μπορούμε να περιηγηθούμε στα στοιχεία μιας συλλογής ένα-ένα και να εκτελέσουμε επιθυμητή λογική επεξεργασίας για κάθε στοιχείο.

Γενικά, η χρήση επαναληπτών προσφέρει ευελιξία και εξοικονόμηση μνήμης κατά την επεξεργασία μεγάλων συλλογών δεδομένων, καθώς επιτρέπει την αποφυγή φόρτωσης ολόκληρης της συλλογής στη μνήμη ταυτόχρονα.

Για να κατανοήσουμε καλύτερα τους επαναλήπτες, ας δούμε ένα παράδειγμα

my_list = [1, 2, 3, 4, 5]

# Δημιουργία ενός επαναλήπτη (iterator) για τη λίστα
iter_obj = iter(my_list)

# Επανάληψη μέσω των στοιχείων της λίστας χρησιμοποιώντας τον επαναλήπτη
for i in iter_obj:
    print(i)  # Εκτύπωση του τρέχοντος στοιχείου της λίστας

Ο παραπάνω κώδικας εκτελεί τις παρακάτω ενέργειες:

  1. Δημιουργεί μια λίστα με τις τιμές [1, 2, 3, 4, 5] και την αποθηκεύει στη μεταβλητή my_list.
  2. Χρησιμοποιεί τη συνάρτηση iter() για να δημιουργήσει έναν επαναλήπτη (iterator) με βάση τη λίστα my_list και τον αποθηκεύει στη μεταβλητή iter_obj.
  3. Εκτελεί μια δομή επανάληψης for, η οποία επαναλαμβάνεται για κάθε στοιχείο της λίστας my_list. Κατά την επανάληψη, κάθε στοιχείο από τη λίστα αποθηκεύεται στη μεταβλητή i.
  4. Εντός της επανάληψης, το τρέχον στοιχείο i εκτυπώνεται στην οθόνη με τη χρήση της συνάρτησης print().

Έτσι, ο κώδικας εκτυπώνει σειριακά τα στοιχεία της λίστας my_list, δηλαδή τα αριθμητικά 1, 2, 3, 4 και 5.

Το παρακάτω παράδειγμα, το οποίο χρησιμοποιεί την iter() και next() για να επιστρέψει το επόμενο στοιχείο από μια λίστα κάθε φορά που καλείται η next() μέθοδος του αντικειμένου iterator:

my_list = [1, 2, 3, 4, 5]

# Δημιουργία ενός επαναλήπτη για τη λίστα
iter_obj = iter(my_list)

# Εκτύπωση του επόμενου στοιχείου από τη λίστα
print(next(iter_obj))  # Εκτυπώνει '1'
print(next(iter_obj))  # Εκτυπώνει '2'
print(next(iter_obj))  # Εκτυπώνει '3'

Ο παραπάνω κώδικας χρησιμοποιεί την iter() για να δημιουργήσει έναν επαναλήπτη από τη λίστα my_list. Στη συνέχεια, κάθε φορά που καλείται η μέθοδος next() στον επαναλήπτη, επιστρέφεται το επόμενο στοιχείο από τη λίστα.

[adinserter block=”2″]

Στο παράδειγμα, εκτυπώνονται τα επόμενα τρία στοιχεία της λίστας, δηλαδή τα αριθμητικά 1, 2 και 3.

Ακόμα και οι συμβολοσειρές στην Python είναι αντικείμενα με δυνατότητα επανάληψης (iterable objects) και μπορούν να παράγουν έναν επαναλαμβανόμενο αντικείμενο (iterator).

Ένα παράδειγμα που δημιουργεί ένα αντικείμενο iterator από μια συμβολοσειρά και επιστρέφει τους χαρακτήρες της συμβολοσειράς έναν έναν:

my_string = "Hello World"  # Αρχικοποίηση της μεταβλητής my_string με την τιμή "Hello World"
my_iterator = iter(my_string)  # Μετατροπή του my_string σε iterator και αποθήκευση του αποτελέσματος στη μεταβλητή my_iterator

# Εκτύπωση των επόμενων στοιχείων του iterator με τη χρήση της συνάρτησης next()
print(next(my_iterator))  # Εκτύπωση του πρώτου στοιχείου του iterator
print(next(my_iterator))  # Εκτύπωση του δεύτερου στοιχείου του iterator
print(next(my_iterator))  # Εκτύπωση του τρίτου στοιχείου του iterator
print(next(my_iterator))  # Εκτύπωση του τέταρτου στοιχείου του iterator
print(next(my_iterator))  # Εκτύπωση του πέμπτου στοιχείου του iterator
print(next(my_iterator))  # Εκτύπωση του έκτου στοιχείου του iterator
print(next(my_iterator))  # Εκτύπωση του έβδομου στοιχείου του iterator
print(next(my_iterator))  # Εκτύπωση του όγδοου στοιχείου του iterator
print(next(my_iterator))  # Εκτύπωση του ενάτου στοιχείου του iterator
print(next(my_iterator))  # Εκτύπωση του δέκατου στοιχείου του iterator

Ο παραπάνω κώδικας δημιουργεί μια μεταβλητή my_string με την τιμή “Hello World” και μετατρέπει αυτήν την αλφαριθμητική τιμή σε έναν iterator με τη χρήση της συνάρτησης iter(). Έπειτα, χρησιμοποιεί τη συνάρτηση next() για να εκτυπώσει τα επόμενα στοιχεία του iterator.

Κατά την εκτέλεση του κώδικα, κάθε φορά που καλείται η συνάρτηση next(my_iterator), επιστρέφεται το επόμενο στοιχείο του iterator και εκτυπώνεται. Έτσι, στην πρώτη επανάληψη εκτυπώνεται το πρώτο γράμμα “H”, στη δεύτερη επανάληψη το “e”, στην τρίτη το “l” κ.ο.κ. Η διαδικασία συνεχίζεται μέχρι να εκτυπωθούν όλα τα γράμματα του αλφαριθμητικού.

Έτσι, ο κώδικας εκτυπώνει τα γράμματα του αλφαριθμητικού “Hello World” ένα προς ένα.

Παρακάτω παρατίθεται ένα παράδειγμα χρήσης της συνάρτησης iter() για τη δημιουργία μιας λίστας με ακέραιους αριθμούς:

# Δημιουργία μιας λίστας με ακέραιους αριθμούς
my_list = [1, 2, 3, 4, 5]

# Χρήση της συνάρτησης iter() για να δημιουργήσουμε έναν iterator από τη λίστα
my_iterator = iter(my_list)

# Εκτύπωση των στοιχείων της λίστας με χρήση του iterator
for num in my_iterator:
    print(num)

Στο παραπάνω παράδειγμα, η συνάρτηση iter() χρησιμοποιείται για να δημιουργήσει έναν iterator από τη λίστα my_list. Στη συνέχεια, μπορούμε να επαναλάβουμε μέσω των στοιχείων της λίστας χρησιμοποιώντας τον iterator μέσα σε έναν βρόχο for. Κάθε στοιχείο της λίστας εκτυπώνεται ξεχωριστά.

Ακολουθεί ένα παράδειγμα χρήσης της συνάρτησης iter() για να περιηγηθούμε σε μια λίστα με strings:

my_list = ["apple", "banana", "cherry"]

# Αρχικοποίηση του iterator
my_iter = iter(my_list)

# Επανάληψη με χρήση του iterator
for item in my_iter:
    print(item)  # Εκτύπωση του τρέχοντος στοιχείου

# Ή μπορούμε να χρησιμοποιήσουμε τη συνάρτηση next() για να πάρουμε το επόμενο στοιχείο
# while True:
#     try:
#         item = next(my_iter)
#         print(item)
#     except StopIteration:
#         break

Στο παραπάνω παράδειγμα, δημιουργούμε μια λίστα my_list με strings. Στη συνέχεια, χρησιμοποιούμε τη συνάρτηση iter() για να δημιουργήσουμε ένα iterator με την ίδια λίστα. Έπειτα, χρησιμοποιούμε έναν βρόχο for για να επαναλάβουμε μέσω των στοιχείων της λίστας και να τα εκτυπώσουμε ένα-ένα.

Μπορούμε επίσης να χρησιμοποιήσουμε τη συνάρτηση next() για να πάρουμε το επόμενο στοιχείο από τον iterator. Σε αυτήν την περίπτωση, θα χρησιμοποιήσουμε έναν βρόχο while και την εξαίρεση StopIteration για να επαναλάβουμε μέχρις ότου ο iterator να εξαντληθεί.

[adinserter block=”3″]

Ένα παράδειγμα με χρήση της συνάρτησης iter() για τη δημιουργία ενός tuple με ακέραιους αριθμούς:

start = 1
end = 10

# Χρήση της συνάρτησης iter() για να δημιουργήσουμε ένα iterator
integer_iter = iter(range(start, end+1))

# Χρήση της συνάρτησης tuple() για να μετατρέψουμε το iterator σε tuple
integer_tuple = tuple(integer_iter)

print(integer_tuple)  # Εκτύπωση του tuple με τους ακέραιους αριθμούς από 1 έως 10

Στο παραπάνω παράδειγμα, χρησιμοποιούμε την iter() για να μετατρέψουμε την ακολουθία από το start έως το end σε έναν iterator. Έπειτα, χρησιμοποιούμε την tuple() για να μετατρέψουμε τον iterator σε ένα tuple που περιέχει τους ακέραιους αριθμούς. Τέλος, εκτυπώνουμε το tuple που δημιουργήθηκε.

Ένα παράδειγμα κώδικα που δημιουργεί ένα λεξικό με strings ως κλειδιά και τιμές χρησιμοποιώντας την συνάρτηση iter() είναι το παρακάτω:

keys = ["apple", "banana", "cherry"]
values = [2, 3, 5]

my_dict = dict(zip(iter(keys), iter(values)))

print(my_dict)

Στο παραπάνω παράδειγμα, οι λίστες keys και values περιέχουν τα κλειδιά και τις τιμές αντίστοιχα. Χρησιμοποιώντας την iter() μεθοδολογία, μετατρέπουμε τις λίστες σε αντικείμενα επαναληπτών. Στη συνέχεια, χρησιμοποιούμε τη συνάρτηση zip() για να συνδέσουμε τα αντικείμενα επαναληπτών και δημιουργούμε ζεύγη (κλειδί, τιμή). Τέλος, χρησιμοποιούμε τη συνάρτηση dict() για να μετατρέψουμε τα ζεύγη σε ένα λεξικό. Το αποτέλεσμα εκτυπώνεται με τη χρήση της εντολής print().

Παρακάτω παρουσιάζεται ένα παράδειγμα χρήσης της συνάρτησης iter() για τη δημιουργία ενός σετ με ακέραιους αριθμούς:

# Δημιουργία ενός iterator με ακέραιους αριθμούς από το 1 έως το 5
my_iterator = iter(range(1, 6))

# Μετατροπή του iterator σε σετ
my_set = set(my_iterator)

# Εκτύπωση του σετ
print(my_set)

Το παραπάνω παράδειγμα παράγει το αποτέλεσμα:

{1, 2, 3, 4, 5}

Χρησιμοποιώντας τη συνάρτηση iter() σε έναν iterator, μπορούμε να δημιουργήσουμε ένα σετ που περιέχει τα στοιχεία του iterator. Στο παράδειγμα, χρησιμοποιούμε την range(1, 6) για να δημιουργήσουμε ένα iterator με τους ακέραιους αριθμούς από το 1 έως το 5. Στη συνέχεια, μετατρέπουμε το iterator σε σετ χρησιμοποιώντας τη συνάρτηση set(). Το τελικό αποτέλεσμα είναι ένα σετ που περιέχει τους ακέραιους αριθμούς 1, 2, 3, 4, 5.

Για να δημιουργήσετε ένα αντικείμενο ή μια κλάση ως επαναληπτή, πρέπει να υλοποιήσετε τις μεθόδους iter() και next() στο αντικείμενό σας.

Όταν δημιουργείτε μια κλάση στην Python, μπορείτε να ορίσετε μια μέθοδο που ονομάζεται __init__(), η οποία εκτελείται κατά τη δημιουργία του αντικειμένου και σας επιτρέπει να πραγματοποιήσετε αρχικοποίηση των μελών της κλάσης.

Η μέθοδος iter() λειτουργεί με παρόμοιο τρόπο. Μπορείτε να πραγματοποιήσετε διάφορες ενέργειες (όπως αρχικοποίηση κλπ.), αλλά πάντα πρέπει να επιστρέφετε το ίδιο αντικείμενο επανάληψης.

[adinserter block=”4″]

Η μέθοδος next() σας επιτρέπει να εκτελέσετε επιπλέον ενέργειες και πρέπει να επιστρέφει το επόμενο στοιχείο στη σειρά.

Ας δημιουργήσουμε έναν απλό iterator που θα επιστρέφει τους αριθμούς από το 1 έως το 5. Αυτό θα μας βοηθήσει να κατανοήσουμε πώς δουλεύουν οι μέθοδοι __iter__() και __next__().

class MyNumbers:
  def __iter__(self):
    self.n = 1  # Αρχικοποίηση του αρχικού αριθμού (n) με την τιμή 1
    return self

  def __next__(self):
    if self.n <= 5:  # Έλεγχος αν ο αριθμός (n) είναι μικρότερος ή ίσος του 5
      x = self.n  # Αποθήκευση της τρέχουσας τιμής του αριθμού (n) στη μεταβλητή (x)
      self.n += 1  # Αύξηση της τιμής του αριθμού (n) κατά 1 για την επόμενη επανάληψη
      return x  # Επιστροφή της τρέχουσας τιμής του αριθμού (x)
    else:
      raise StopIteration  # Εκτέλεση της εξαίρεσης StopIteration για τη λήξη της επανάληψης

numbers = MyNumbers()  # Δημιουργία ενός αντικειμένου MyNumbers
my_iter = iter(numbers)  # Παίρνουμε ένα iterator από το αντικείμενο MyNumbers

for number in my_iter:  # Επανάληψη για κάθε αριθμό στον iterator
  print(number)  # Εκτύπωση του αριθμού

Ο παραπάνω κώδικας δημιουργεί μια κλάση με όνομα “MyNumbers” που υλοποιεί το πρωτόκολλο επανάληψης στην Python. Η κλάση έχει δύο μεθόδους: τη μέθοδο __iter__() και τη μέθοδο __next__().

Η μέθοδος __iter__() αρχικοποιεί τον αρχικό αριθμό (n) με την τιμή 1 και επιστρέφει τον εαυτό της ως αντικείμενο επανάληψης.

Η μέθοδος __next__() ελέγχει αν ο αριθμός n είναι μικρότερος ή ίσος του 5. Αν ισχύει αυτή η συνθήκη, αποθηκεύει την τρέχουσα τιμή του n στη μεταβλητή x, αυξάνει την τιμή του n κατά 1 για την επόμενη επανάληψη και επιστρέφει την τρέχουσα τιμή του x. Αν ο αριθμός n είναι μεγαλύτερος από το 5, η μέθοδος εκτελεί μια εξαίρεση StopIteration για να σταματήσει την επανάληψη.

Στη συνέχεια, δημιουργείται ένα αντικείμενο numbers της κλάσης MyNumbers και από αυτό παίρνουμε ένα iterator με τη χρήση της συνάρτησης iter(). Έπειτα, χρησιμοποιούμε τον iterator σε μια δομή επανάληψης for για να εκτυπώσουμε τους αριθμούς από τον iterator. Η κάθε επανάληψη εκτυπώνει την τρέχουσα τιμή του αριθμού number μέχρις ότου η εξαίρεση StopIteration να εκτελεστεί και να τερματιστεί η επανάληψη.

7 Ιουνίου, 2023
top
error: Content is protected !!
Μετάβαση σε γραμμή εργαλείων