تكرار السؤال: …
الإجابة المختصرة
الـ iterable كائن يمكن الحصول منه على iterator عبر iter() (مثل list)، أما الـ iterator فيحفظ موضعه ويعيد العنصر التالي عبر next() ويُستهلك مرة واحدة فقط.
الشرح
يمكنك المرور على list عدة مرات لأن كل حلقة تنشئ iterator جديدًا. أما generator أو file object فهما iterators؛ بعد استهلاكهما لن تعيد الحلقة الثانية أي عناصر. لذلك إذا مررت generator لدالتين، ستجد الثانية البيانات فارغة. إذا احتجت المرور أكثر من مرة، حوّل النتيجة إلى list أو أعد إنشاء الـ generator.
مثال بالكود
numbers = (n * n for n in range(3)) # generator = iterator
print(sum(numbers)) # 5
print(sum(numbers)) # 0 — استُهلك بالفعل
items = [1, 2, 3] # iterable
it = iter(items)
print(next(it), next(it)) # 1 2أخطاء شائعة
- إعادة استخدام generator بعد استهلاكه وتوقع الحصول على نفس البيانات.
- تحويل كل iterator إلى list مبكرًا مما يلغي فائدة المعالجة الكسولة.
أسئلة متابعة
- ما البروتوكول الذي يجعل الكائن قابلًا للاستخدام في حلقة for؟
- كيف تقلل generators و yield استهلاك الذاكرة؟