for في بايثون

من موسوعة حسوب

تختلف عبارة for قليلًا في بايثون عن نظيرتها في لغتي C أو Pascal، فبدلًا من تكرار الحلقة استنادًا إلى عملية حسابية (مثل لغة Pascal) أو منح المستخدم القدرة على تعريف عدد مرات التكرار والشرط الذي يؤدي إلى إيقاف عمل الحلقة (كما في لغة C)، فإنّ عبارة for في بايثون تمرّ على عناصر أي تسلسل (قائمة أو سلسلة نصية) معتمدة في ذلك على ترتيب تلك العناصر في ذلك التسلسل.

بنية عبارة for

>>> # معرفة أطوال السلاسل النصية:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
...
cat 3
window 6
defenestrate 12

إن كانت هناك حاجة لتعديل التسلسل الذي تمرّ عليه الحلقة أثناء عملها (مضاعفة العنصر المحدّد مثلًا) فينصح بإنشاء نسخة في البداية، إذ أنّ المرور على عناصر التسلسل لا يؤدي إلى إنشاء نسخة بصورة ضمنية، ويمكن القيام بذلك باستخدام علامة الاقتطاع slice notation:

>>> for w in words[:]:  # المرور على نسخة مقتطعة لكامل السلسلة النصية:
...     if len(w) > 6:
...         words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

في حال استخدام العبارة for w in words:‎، ستنشئ حلقة for قائمة ذات عدد غير منتهٍ من العناصر، وستدرج عبارة defenestrate دون توقّف.

الدالة range()‎

يمكن استخدام الدالة range() للمرور على تسلسل من الأرقام، إذ تنتج هذه الدالة تسلسلًا حسابيًا كما في المثال التالي:

>>> for i in range(5):
...     print(i)
...
0
1
2
3
4

لا يدخل الرقم الأخير ضمن التسلسل الذي تنشئه الدالة، فمثلًا تنشئ الدالة range(10)‎ عشر قيمٍ تبدأ من الرقم 0 وتنتهي بالرقم 9. يمكن تحديد الرقم الذي يبدأ به التسلسل، أو تحديد طريقة زيادة الأرقام (يطلق عليها في بعض الأحيان "الخطوات Steps") ضمن التسلسل، كما يمكن تعيين قيم سالبة:

range(5, 10)
   5, 6, 7, 8, 9

range(0, 10, 3)
   0, 3, 6, 9

range(-10, -100, -30)
  -10, -40, -70

للمرور على فهارس عناصر التسلسل، يمكن استخدام الدالتين range()‎ وlen()‎ معًا كما يلي:

>>>
>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb

ولكن في مثل هذه الحالات، يفضّل استخدام الدالة enumerate()‎، وللاطلاع بصورة أوسع على هذا الموضوع راجع أساليب استخدام الحلقات.

يؤدي طباعة دالة range() إلى الحصول على نتائج غريبة بعض الشيء:

>>> print(range(10))
range(0, 10)

في كثير من الأحيان يسلك الكائن المعاد من الدالة range()‎ سلوك القائمة، ولكنّه في الواقع ليس كذلك. فهو كائن يعيد عناصر متتالية للتسلسل المطلوب عند المرور على تلك العناصر، ولكنّه لا ينشئ القائمة في الواقع، ليوفّر بذلك بعض المساحة في الذاكرة.

المقصود بالكائن القابل للتكرار iterable object هو أنّ هذا الكائن ملائم كهدف للدوال والبنى التي تتوقع الحصول على مجموعة من العناصر المتتالية، وتعدّ عبارة for واحدة من العبارات التي تعطي عناصر متتالية. الدالة list()‎ هي مثال آخر، إذ تنشئ هذه الدالة قوائم من الكائنات القابلة للتكرار:

>>> print(range(10))
range(0, 10)

عبارتا break و else

كما هو الحال في لغة C يؤدّي استخدام عبارة break إلى الخروج من حلقة for أو while المحيطة بها.

يمكن استخدام عبارة else مع الحلقات التكرارية، ويجري تنفيذها عند استنفاد قائمة العناصر (في حلقة for) أو عندما يعطي الشرط نتيجة خاطئة (في حلقة while)، ولكن لا تنفّذ عبارة else عند إيقاف عمل الحلقة بواسطة عبارة break. في المثال التالي تبحث الحلقة عن الأعداد الأولية، لاحظ أنّ عبارة else في هذا المثال تابعة لحلقة for وليست لعبارة if:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, '=', x, '*', n//x)
...             break
...     else:
...         # فشلت الحلقة في العثور على أي عامل
...         print(n, 'عدد أولي')
...
2 عدد أولي
3 عدد أولي
4 = 2 * 2
5 عدد أولي
6 = 2 * 3
7 عدد أولي
8 = 2 * 4
9 = 3 * 3

تشبه عبارة else في الحلقات التكرارية عبارة else في تعبير try أكثر ممّا تشبه عبارة else في تعبير if، إذ تعمل عبارة else في تعبير try عندما لا يحدث أي استثناء، وكذلك تعمل عبارة else عندما لا تتوقف الحلقة عن التكرار break.

للاطلاع بصورة أكبر على عبارة try والاستثناءات راجع التعامل مع الاستثناءات.

عبارة continue

تنقل عبارة continue، والمأخوذة من لغة C، عملية التنفيذ إلى الدورة التالية من الحلقة:

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9

مصادر