איטראטור - iterator

February 15, 2019

איטראטור - iterator

כדי להבין מהו איטרטור אנו צריכים להבין איזה מין אובייקט הוא iterable – טוב בפייתון יש הרבה אובייקטים המוגדרים iterables , ביניהם רשימות, טופלים, מילונים, סטים ומחרוזות המשמעות של המילה היא שניתן לעבור דרך אותו אובייקט, על כל איבריו, אחד אחד, לפי הסדר, ולעשות עם כל איבר של האובייקט משהוא בנפרד. לפעמים באמצעות הפקודה for  -

 

 

for i in "abcd":
    print(i)

>>>

a

b

c

d

 

המחרוזת "abcd" מאפשר ריצה בתוכה על כל אחד מהאיברים שלה והדפסתו למשל.

האובייקטים הללו יכולים לקבל את המתודה ()iter באופן שבאמצעות הפקודה next ניתן לעבור אחד אחד – להלן ניצור איטרטור בעל השם המקורי iterator, אשר יצירתו מתאפשרת אודות לפקודה iter() שהפעלנו על הרשימה שלנו lista (שהיא כאמור iterable).לנשום לשקית נייר חומה ואז לקרוא שוב במידת הצורך.

 

lista=[2,4,6,8,10]
iterator=iter(lista)

print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))

 

>>>

2

4

6

8

10

 

האיטרטור מאפשר לנו לעבור על איברי הרשימה, אולם מה קורה כאשר סיימנו ? את האיברים ברשימה? האם הוא מתחיל מחדש ? לא. הוא מוציא הודעת שגיאה ובעצם יוצא מכלל פעולה. על זה אנו אומרים שהאיטרטור נוצל או באנגלית (consumed) .

מה שעושה לולאת for עבורנו, עכשיו מותר לגלות, זה בעצם לייצר איטרטור ולהפעיל אותו על איברי האובייקט האיטרבילי (רשימה, טופל, מחרוזת וכו') שלנו.

בואו נייצר איטרטור נחמד שיכול להמשיך לנצח, האיבר הראשון שהוא מדפיס הוא 1 האיבר אחריו כפול ממנו, וכך הלאה עד אין קץ (או שהזיכרון נגמר או משהו) –

 

class Multi2:
  def __iter__(self):
    self.num = 1
    return self

  def __next__(self):
    mul = self.num
    self.num *= 2
    return mul

multiclass = Multi2()
doubleIterator = iter(multiclass)

print(next(doubleIterator))
print(next(doubleIterator))
print(next(doubleIterator))
print(next(doubleIterator))
print(next(doubleIterator))
print(next(doubleIterator))

 

>>>

1

2

4

8

16

32

 

הסבר- בנינו מחלקה שנקראת Multi2 שיש בה שתי פונקציות/מתודות מיוחדות  __iter__ ו- __next__ שיהפכו את המופע שלנו (multiclass) לאיטרטור אינסופי שיפלוט מספרים כל פעם בגודל כפול מהפעם הקודמת. זאת באמצעות השמה במשתנה בשם doubleIterator (האיטרטור שלנו) את המופע (multiclass) כשהוא עטוף בפקודת ()iter.

ניתן לייצר מכל אובייקט איטרבילי כמה איטרטורים שאנו רוצים וכל אחד מהם יפעל באופן עצמאי -  

 

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

it1=iter(lista)
it2=iter(lista)

print(next(it1))
print(next(it1))
print(next(it2))

 

>>>

1

2

1

 

כאמור, כל אחד מהאיטרטורים רץ בנפרד עד שהוא מנוצל במלואו (consumed) ואז הוא מוציא הודעת שגיאה אם מנסים להוציא ממנו יותר ממה שיש בו.

הפקודה ()range – מזכירה בהתנהגותה איטרטור, אם כי יש לה מאפיינים מעט שונים, ויש המכנים אותה איטרטור עצל (למה להעליב)- נושא לויכוח בקרב יודעי דבר ברשת.

Please reload

Please reload

רעננו את הדף והקליקו למעבר לנושא הבא: