التحكم بشكل فعال في حلقات بايثون

سنعرض لك في هذه المقالة بعض الطرق المختلفة لإنهاء حلقة في بايثون. قد يبدو هذا تافهًا بعض الشيء في البداية، ولكن هناك بعض المفاهيم المهمة التي يجب فهمها حول بيانات التحكم. سنقدم أيضًا بعض الطرق الأقل شهرة لإنهاء الحلقات في بايثون لتمنحك أدوات للتحكم بشكل أكبر في كيفية تنفيذ برامجك.

إذا كنت مبتدئًا في لغة Python، فنوصيك بالبدء بهذه المقالة لتتعلم بعض المصطلحات التي نستخدمها.

التكرار مع الحلقات

نقطة الدخول هنا تستخدم حلقة for لإجراء التكرارات. تعد حلقة for أحد أهم المفاهيم الأساسية في لغة بايثون. سوف تصادفها في العديد من السياقات، ويعد فهم كيفية عملها خطوة أولى مهمة.

حلقة for هي طريقة للتكرار على مجموعة من البيانات. قد تكون البيانات رقمية، على سبيل المثال، رقم الفاصلة العائمة أو عدد صحيح، أو حتى بيانات نصية، ويمكن تخزينها في هياكل مختلفة بما في ذلك القوائم والصفوف والمجموعات والقواميس.

لم ينته الأمر حتى انتهى

لقد كان هذا الحشو اللغوي شعارًا للعديد من المستضعفين في المنافسة. إنها أيضًا المحطة الأولى في مناقشتنا حول كيفية إنهاء حلقة في بايثون. يمكننا تحديد تكرار للتكرار مع أي من بنيات البيانات المذكورة أعلاه. وبدلاً من ذلك، يمكننا أيضًا استخدام الدالة RANGE()‎ المضمنة، والتي تُرجع تسلسلًا غير قابل للتغيير.

يقبل range() ثلاث وسيطات أعداد صحيحة: start (optional, default 0)، وstop (required)، وstep (optional, default 1). تقوم بإرجاع تسلسل بعدد محدد مسبقًا من العناصر.

يمكننا تكرار العناصر بالتسلسل كما يلي:

>>> for i in range(-2, 11, 3):
>>>     print(i)
-2
1
4
7
10

هناك بعض الأشياء المثيرة للاهتمام حول هذا المثال. أولاً، يمكن أن تكون الوسيطات سلبية. يمكنك حتى تحديد خطوة سلبية للعد التنازلي. جربه بنفسك. ثانيا، الوصول إلى قيمة التوقف المحددة غير مطلوب. في المثال أعلاه، نتقدم عبر التسلسل الذي يبدأ عند -2، ونتخذ خطوات من 3، ثم نتوقف عند 10. وهذا قبل قيمة التوقف المحددة البالغة 11، ولكن الخطوة الإضافية البالغة 3 تأخذنا إلى ما هو أبعد من قيمة التوقف. هذه هي الطريقة الأكثر وضوحًا لإنهاء حلقة في بايثون – بعد عدد محدد مسبقًا من التكرارات.

إذا كنت تريد التكرار على بعض البيانات، فهناك بديل للحلقة for التي تستخدم الدوال المضمنة iter() وnext(). يحدد الأول مكررًا من عنصر قابل للتكرار، بينما يقوم الأخير بإرجاع العنصر التالي من المكرر. تنتهي الحلقة، أو التكرار، بمجرد إرجاع العنصر الأخير من المكرر. يؤدي استدعاء next() بعد ذلك إلى ظهور استثناء StopIteration. يمكنك التكرار مرة واحدة فقط مع هذه الدوال لأن العنصر القابل للتكرار لا يتم تخزينه في الذاكرة، ولكن هذه الطريقة أكثر كفاءة عند التعامل مع كميات كبيرة من البيانات.

عبارات التحكم في الحلقة

break

عبارة Break هي الأولى من بين ثلاث عبارات للتحكم في الحلقة في بايثون. يتم استخدامه مع العبارات الشرطية (if-elif-else) لإنهاء الحلقة مبكرًا في حالة استيفاء بعض الشروط. على وجه التحديد، توفر عبارة Break طريقة للخروج من الحلقة بالكامل قبل انتهاء التكرار. يوضح المثال التالي هذا السلوك:

>>> for i in range(5):
>>>     if i == 3:
>>>         break
>>>     print(i)
>>> print('Finished')
0
1
2
Finished

نحن نستخدم range() عن طريق تحديد وسيطة الإيقاف المطلوبة فقط. في هذه الحالة، تأخذ وسيطتا البداية والخطوة قيمهما الافتراضية 0 و1، على التوالي. ببساطة، سيؤدي التكرار عبر range(5) إلى طباعة القيم من 0 إلى 4. وبدلاً من ذلك، نتحقق مما إذا كان العنصر يساوي 3، وإذا كان الأمر كذلك، فستقوم عبارة Break بإيقاف الحلقة تمامًا. السطر الأخير، print('Finished') موجود خارج الحلقة، وبالتالي لا يزال يتم تنفيذه بعد كسر الحلقة.

continue

قارن هذا مع عبارة continue، كما هو موضح أدناه:

>>> for i in range(5):
>>>     if i==3:
>>>         continue
>>>     print(i)
>>> print('Finished')
0
1
2
4
Finished

بمجرد تقييم الشرط في السطر الثاني إلى True، تتخطى عبارة continue عبارة print داخل الحلقة. ثم يستمر في تنفيذ الحلقة عند العنصر التالي. تنتهي الحلقة عند الوصول إلى العنصر الأخير. يعد هذا مفيدًا إذا كنت تريد إكمال الحلقة ولكنك تريد تخطي بعض العناصر فقط. وكما رأينا أعلاه، سيتم تنفيذ أي تعليمات برمجية موجودة أسفل الحلقة وخارجها.

pass

عبارة التحكم في الحلقة الثالثة هو pass. بالمعنى الدقيق للكلمة، هذه ليست طريقة للخروج من حلقة في بايثون. ومع ذلك، فمن الجدير بالذكر لأنه يظهر غالبًا في سياقات مشابهة لعبارات التحكم الأخرى. جرب المثال أعلاه باستخدام عبارة pass بدلاً من continue، وستلاحظ أن جميع العناصر المحددة بواسطة range() مطبوعة على الشاشة. تعمل عبارة pass كعنصر نائب للتعليمات البرمجية التي قد ترغب في إضافتها لاحقًا مكانها.

الاختلافات بين عبارات التحكم الثلاثة (Break, Continue, Pass)

1. Break:

  • تُستخدم عبارة break لإنهاء حلقة for أو while بشكل فوري.
  • متى نستخدمها؟
    • عندما نريد الخروج من حلقة فورًا عند تحقق شرط معين.
    • عندما نريد تجاوز باقي التعليمات داخل الحلقة.
  • مثال:
for i in range(10):
    if i == 5:
        break
    print(i)
  • ستقوم الحلقة بطباعة الأرقام من 0 إلى 4.
  • عند وصول i إلى 5، ستقوم عبارة break بإنهاء الحلقة بشكل فوري.
  • لن تتم طباعة الأرقام من 6 إلى 9.

2. Continue:

  • تُستخدم عبارة continue لتخطي باقي التعليمات داخل حلقة for أو while ثم الانتقال إلى التكرار التالي.
  • متى نستخدمها؟
    • عندما نريد تجاوز بعض التعليمات داخل الحلقة دون إنهاءها.
  • مثال:
for i in range(10):
    if i % 2 == 0:
        continue
    print(i)
  • ستقوم الحلقة بطباعة الأرقام الفردية فقط من 1 إلى 9.
  • عند وصول i إلى رقم زوجي، ستقوم عبارة continue بتخطي باقي التعليمات داخل الحلقة والانتقال إلى التكرار التالي.

3. Pass:

  • تُستخدم عبارة pass كتعليمة فارغة داخل حلقة أو دالة أو تعريف فئة.
  • متى نستخدمها؟
    • عندما نحتاج إلى كتابة تعريف لحلقة أو وظيفة أو تعريف فئة دون كتابة أي تعليمات داخلها في الوقت الحالي.
    • عندما نريد ترك مكان لكتابة تعليمات لاحقًا.
  • مثال:
def my_function():
    pass

class MyClass:
    pass

تم تعريف دالة my_function و فئة MyClass بدون كتابة أي تعليمات داخلها.

يمكننا كتابة تعليمات داخل هذه الدالة و الفئة لاحقًا.

انتقل إلى مخرج الطوارئ في بايثون

توضح الميزات التي رأيناها حتى الآن كيفية الخروج من حلقة في بايثون. إذا كنت تريد الخروج من برنامج بشكل كامل قبل أن تصل إلى النهاية، فإن وحدة sys توفر هذه الوظيفة من خلال دالة exit() . يؤدي استدعاء هذه الدالة إلى ظهور استثناء SystemExit وإنهاء البرنامج بأكمله.

يقبل sys.exit() وسيطة اختيارية واحدة. قد تكون إما عددًا صحيحًا أو سلسلة، والتي يمكن استخدامها لطباعة رسالة خطأ على الشاشة.

دعونا نلقي نظرة على مثال:

>>> import sys
>>> for i in range(5):
>>>     if i == 3:
>>>         sys.exit('Error message')
>>>     print(i)
>>> print('Finished')
0
1
2
SystemExit: Error message

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

التكرار على القوائم

إحدى العمليات الشائعة التي يتم إجراؤها في الحلقة هي تعديل بنية البيانات مثل القائمة. إذا كنت تريد إزالة عنصر من القائمة أثناء التكرار، فقد تجد نفسك تبحث عن الكلمة الأساسية del، خاصة إذا كان لديك خلفية في لغات البرمجة الأخرى مثل C++ أو Java.

يمكن أن تكون هذه أداة مفيدة حيث يمكنها إزالة العناصر من هياكل البيانات بالإضافة إلى حذف المتغيرات المحلية أو العالمية. ولكن قد يصبح الأمر صعبًا بعض الشيء إذا كنت تقوم بتغيير القائمة أثناء تكرارها.

خذ بعين الاعتبار المثال التالي، حيث نريد إزالة كافة الأرقام الفردية من قائمة الأرقام:

>>> numbers = [1, 1, 2, 3, 4, 5, 6]
>>> for i in range(len(numbers)):
...     if numbers[i] % 2 != 0:
...         del numbers[i]

سيؤدي تنفيذ هذا الرمز إلى ظهور خطأ IndexError: list index out of range. لقد حددنا حلقتنا للتنفيذ لمدة 7 تكرارات (طول القائمة). وبما أننا قمنا بتعريف ذلك باستخدام range()، فهو غير قابل للتغيير. أثناء الحلقة، نبدأ في إزالة العناصر من القائمة، مما يؤدي إلى تغيير طولها. يحتوي الآن على عناصر أقل من التسلسل الذي نريد التكرار عليه. علاوة على ذلك، إذا أخذت لحظة للنظر في المثال، سترى أن الرقم 1 الثاني لن يتم حذفه لأنه ينزلق إلى الموضع 0 بينما تنتقل الحلقة إلى الموضع مع الفهرس 1.

لمعالجة كل هذا، يمكننا استخدام خدعة ذكية للتكرار على العناصر بترتيب عكسي، باستخدام الدالة المضمنة Reverse() :

>>> numbers = [1, 1, 2, 3, 4, 5, 6]
>>> for i in reversed(range(len(numbers))):
...     if numbers[i] % 2 != 0:
...         del numbers[i]

تقوم الدالة reversed() بإرجاع مكرِّر، وهو ما ذكرناه سابقًا في المقالة. بدلًا من ذلك، يمكنك استخدام range() للعد التنازلي أثناء التكرار كما أشرنا سابقًا. تعمل هذه التوابع على إزالة العناصر من نهاية القائمة، مما يضمن ألا يكون فهرس القائمة الحالي أكبر من طول القائمة.

أو الأفضل من ذلك، يمكننا استخدام النهج الأكثر بايثونية، وهو فهم القائمة، والذي يمكن تنفيذه على النحو التالي:

>>> numbers = [1, 1, 2, 3, 4, 5, 6]
>>> numbers = [num for num in numbers if num % 2 == 0]

الأخطاء الشائعة عند استخدام حلقات بايثون وكيفية تجنبها

تُعدّ الحلقات من أهمّ أدوات التحكم في تدفق البرنامج في لغة بايثون، لكنّ استخدامها قد يُؤدّي إلى بعض الأخطاء الشائعة، إليك بعضًا منها مع كيفية تجنّبها:

تعديل عناصر القائمة أثناء المرور عليها:

يحدث هذا الخطأ عند محاولة إضافة أو حذف عناصر من قائمة أثناء المرور عليها باستخدام حلقة for.

numbers = [1, 2, 3, 4, 5]
for number in numbers:
  if number == 3:
    numbers.append(6)

print(numbers)  # الناتج: [1, 2, 3, 6, 5]

الحل:

إنشاء قائمة جديدة: قم بإنشاء قائمة جديدة لإضافة العناصر إليها بدلاً من تعديل القائمة الأصلية أثناء المرور عليها.

numbers = [1, 2, 3, 4, 5]
new_numbers = []
for number in numbers:
  if number == 3:
    new_numbers.append(6)
  new_numbers.append(number)

print(numbers)  # الناتج: [1, 2, 3, 4, 5]
print(new_numbers)  # الناتج: [1, 2, 3, 6, 4, 5]

عدم استخدام شرط التوقف

قد تُؤدّي بعض الحلقات إلى التكرار اللانهائي إذا لم يتم استخدام شرط التوقف بشكل صحيح.

i = 0
while True:
  print(i)
  i += 1

الحل:

  • تحديد شرط التوقف: تأكد من وجود شرط يوقف الحلقة عندما يتم تحقيق الغرض المطلوب.
target_number = 10
i = 0
while i < target_number:
  print(i)
  i += 1

نسيان تهيئة المتغير

قد تُؤدّي بعض الحلقات إلى حدوث أخطاء إذا لم يتم تهيئة المتغيرات المستخدمة داخلها بشكل صحيح قبل بدء الحلقة.

for i in range(10):
  print(i * total)  # المتغير "total" غير معرف

الحل:

  • تهيئة المتغيرات قبل الحلقة: تأكد من تهيئة جميع المتغيرات المستخدمة داخل الحلقة قبل بدءها.
total = 5
for i in range(10):
  print(i * total)

استخدام النوع الخاطئ في شرط الحلقة

قد تُؤدّي بعض الحلقات إلى حدوث أخطاء إذا تم استخدام نوع خاطئ في شرط الحلقة.

for i in "Hello":
  print(i)

الحل:

  • استخدام النوع الصحيح: تأكد من استخدام النوع الصحيح في شرط الحلقة،
for i in range(len("Hello")):
  print("Hello"[i])

احصل على مزيد من التحكم وحلقات النهاية في بايثون

ركزت هذه المناقشة على كيفية الخروج من حلقة في بايثون – على وجه التحديد، كيفية الخروج من حلقة for في بايثون. ونود أن نشجعك على اتخاذ الخطوة التالية وتطبيق ما تعلمته هنا.

كما قلنا من قبل، ابدأ باتخاذ خطوات صغيرة ثم انتقل إلى الأمثلة الأكثر تعقيدًا. حاول تجربة حلقات while. قد تكتشف أن هناك طريقة أكثر أساسية للخروج من حلقة while لا تنطبق على حلقات for – عندما يتم تقييم الشرط المحدد بواسطة عبارة while إلى خطأ.

كملحق آخر، اختبر ما يحدث عند استخدام حلقات for المتداخلة مع عبارات التحكم. ستجد أنه يمكنك تعديل حلقة واحدة، بينما تستمر الأخرى في التنفيذ بشكل طبيعي. مع القليل من التدريب، ستتقن التحكم في كيفية إنهاء حلقة في بايثون.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

اكتشاف المزيد من بايثون العربي

اشترك الآن للاستمرار في القراءة والحصول على حق الوصول إلى الأرشيف الكامل.

Continue reading

Scroll to Top