المكررات في بايثون

المكررات في بايثون

تشرح هذه المقالة المكررات في بايثون۔

YouTube Video

المكررات في بايثون

نظرة عامة

في بايثون، الـمكرر هو آلية أساسية لمعالجة عناصر التجميعات مثل القوائم والصفوف والقواميس واحدًا تلو الآخر۔

ما هو المكرر؟

المكرر هو كائن يمكنه إرجاع العناصر واحدًا تلو الآخر۔ في بايثون، يعتبر الكائن مكرراً إذا حقق الشرطين التاليين:۔

  • يحتوي على دالة __iter__() تُرجع نفسه۔
  • يحتوي على دالة __next__() تُرجع العنصر التالي۔ يقوم بإثارة استثناء StopIteration عندما لا يكون هناك مزيد من العناصر۔
1iterator = iter([1, 2, 3])
2print(next(iterator))  # 1
3print(next(iterator))  # 2
4print(next(iterator))  # 3
5# print(next(iterator))  # StopIteration occurs
  • في هذا الكود، تُستخدم الدالة iter() لتحويل القائمة إلى تكرار (iterator)، وتُستخدم الدالة next() لاسترجاع وعرض كل عنصر واحدًا تلو الآخر.۔

الفرق بين المكرر والقابل للتكرار

القابل للتكرار هو كائن ينفذ دالة __iter__() ويمكن استخدامه في حلقة for۔ القوائم والصفوف أمثلة على الكائنات القابلة للتكرار۔

1nums = [10, 20, 30]
2it = iter(nums)  # Get an iterator from the iterable
3print(next(it))  # 10
  • هذا الكود مثال على الحصول على تكرار (iterator) من كائن قابل للتكرار مثل القائمة واسترجاع العناصر بالترتيب باستخدام next()

كيفية التحقق:

1from collections.abc import Iterable, Iterator
2
3nums = [10, 20, 30]
4it = iter(nums)
5
6print(isinstance(nums, Iterable))  # True
7print(isinstance(nums, Iterator))  # False
8print(isinstance(it, Iterator))    # True
  • يؤكد هذا الكود أن nums كائن قابل للتكرار (iterable) لكنه ليس تكرارًا (iterator)، بينما it، الذي تم الحصول عليه باستخدام iter(nums)، هو تكرار (iterator).۔

العلاقة بين حلقات for والمكررات

تعمل حلقة for في بايثون داخليًا كالتالي:۔

1nums = [1, 2, 3]
2iterator = iter(nums)
3while True:
4    try:
5        value = next(iterator)
6        print(value)
7    except StopIteration:
8        break
  • كما هو موضح، تستخدم حلقة for بشكل ضمني مكررًا لإجراء التكرار۔

إنشاء مكرر مخصص

يمكنك إنشاء مكرر مخصص باستخدام الفئة (class)۔

 1class Countdown:
 2    def __init__(self, start):
 3        self.current = start
 4
 5    def __iter__(self):
 6        return self
 7
 8    def __next__(self):
 9        if self.current <= 0:
10            raise StopIteration
11        value = self.current
12        self.current -= 1
13        return value
14
15for num in Countdown(3):
16    print(num)  # 3, 2, 1
  • يُعرّف هذا الكود تكرارًا مخصصًا يعد تنازليًا باستخدام فئة Countdown ويطبع الأرقام من 3 إلى 1 باستخدام حلقة for

الفرق بين المكررات والمولّدات، ومتى يتم استخدام كل منهما

المولدات توفر وظيفة مشابهة للمكررات۔ تسمح لك بتعريف المكررات بشكل أكثر اختصارًا۔

1def countdown(n):
2    while n > 0:
3        yield n
4        n -= 1
5
6for i in countdown(3):
7    print(i)  # 3, 2, 1
  • يُعرّف هذا الكود دالة مولد (generator) تعد تنازليًا باستخدام yield ويطبع الأرقام من 3 إلى 1 باستخدام حلقة for

الاختلافات بين المكررات (كلاس) والمولدات (دالة)

هناك الفروقات التالية بين التكرارات (الفئات) والمولدات (الدوال):۔

الخاصية المكرر (كلاس) المولد (دالة)
التعريف __iter__() + __next__() دالة تستخدم yield
إدارة الحالة يحتاج معالجة الخصائص يدويًا يحتفظ بالحالة تلقائيًا
القابلية للقراءة قد تصبح معقدة بسيطة وواضحة
  • اختلاف في طريقة تعريفهم يتم تعريف المكرر عن طريق كتابة دالتين يدويًا: __iter__() و __next__()۔ أما المولد فهو مجرد دالة تستخدم الكلمة المفتاحية yield، مما يجعل الكود أكثر بساطة۔

  • الاختلاف في إدارة الحالة مع المكرر، يجب إدارة الحالة الحالية والتقدم يدويًا باستخدام المتغيرات۔ بينما تحتفظ المولدات بالحالة تلقائيًا داخليًا في بايثون، مما يقلل من الجهد اليدوي۔

  • قابلية قراءة الكود تميل المكررات إلى أن تصبح معقدة لأنها تتطلب عدة دوال وإدارة يدوية للحالة۔ أما المولدات، فتستخدم بنية بسيطة، مما يسهل فهمها حتى للمبتدئين۔

المكتبة القياسية لاستخدام المكررات: itertools

itertools، وهي مكتبة قياسية في بايثون، توفر أدوات قوية للتعامل مع المكررات۔

1import itertools
2
3for x in itertools.count(10, 2):  # 10, 12, 14, ...
4    if x > 20:
5        break
6    print(x)
  • وتشمل أيضًا العديد من الدوال الأخرى مثل cycle وrepeat وchain وislice وtee۔

حالات استخدام المكررات

تشمل حالات استخدام التكرارات (iterators) ما يلي:۔

  • معالجة أسطر الملفات: قراءة الأسطر واحدًا تلو الآخر من ملف كمكرر۔
  • المعالجة الفعّالة للذاكرة: معالجة كميات كبيرة من البيانات بشكل تسلسلي۔
  • تمثيل التسلسلات غير المنتهية: استخدام دوال مثل itertools.count()۔

الملخص

  • المكرر هو كائن يمكنه جلب القيمة التالية بشكل تسلسلي۔
  • يمكنك إنشاء مكرر مخصص عن طريق تعريف دالتي __iter__() و__next__()۔
  • يتم التعامل معها تلقائيًا عبر حلقات for أو دالة next()۔
  • استخدام المولدات أو مكتبة itertools يتيح معالجة أكثر فعالية۔

باستخدام المكررات، يمكنك معالجة كميات كبيرة من البيانات بشكل تسلسلي وفعّال من حيث الذاكرة، مما يسمح بإدارة محكمة للحالة وتحسين أداء البرنامج۔

يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔

YouTube Video