2.13. التحكم في الحلقات¶
هناك كلمتان مفتاحيتان تغيّران طريقة عمل الحلقة:
break-- الخروج من الحلقة فورًا.continue-- تخطّي بقية التكرار الحالي والبدء بالتكرار التالي.
كلتاهما تنطبق على الحلقة الأكثر داخليةً التي تظهران ضمنها.
2.13.1. break¶
استخدم break لإيقاف الحلقة فور تحقّق شرط معيّن. النمط الكلاسيكي "ابحث ثم توقّف":
found = None
for item in items:
if matches(item):
found = item
break
if found is not None:
print("found:", found)
في حلقة while True:، يكون break هو الطريقة التي تنتهي بها الحلقة:
while True:
line = next_line()
if line == "quit":
break
process(line)
2.13.2. continue¶
استخدم continue لتخطّي بقية جسم الحلقة والقفز إلى التكرار التالي. وهو مفيد لتصفية العناصر داخل الحلقة:
for n in numbers:
if n < 0:
continue # skip negatives
print(n)
يمكن تحقيق التأثير نفسه بكتابة كتلة if تحيط ببقية جسم الحلقة. لكن continue يكون أحيانًا أوضح عندما يكون التعبير عن شرط التخطّي أسهل مقدمًا من التعبير عن شرط الإبقاء.
داخل الحلقة، يؤدّي continue الدور نفسه الذي يؤدّيه return المبكّر داخل الدالة: تخطّي الحالات التي لا تعالجها وإبقاء العمل الرئيسي مستويًا عند الإزاحة الخارجية. وتُعدّ حلقة التصفية والمعالجة هي الشكل النموذجي:
for item in items:
if item is None:
continue
if not item.is_valid():
continue
process(item)
السطر المُزاح process(item) هو العمل الفعلي؛ وكل حارس في الأعلى يوضّح بدقة أيّ العناصر يُتخطّى.
2.13.3. else على الحلقة¶
تقبل كلٌّ من for و while كتلة else اختيارية. وهي تعمل عند اكتمال الحلقة دون أن تصادف break. والاستخدام الأكثر شيوعًا هو حلقة بحث ترغب في بديل احتياطي إذا لم يُعثر على شيء:
for item in items:
if matches(item):
print("found:", item)
break
else:
print("no match")
إذا أُطلق break، فإن كتلة else تُتخطّى. اقرأ هذا التركيب على أنه "من أجل X في Y: ...؛ وإلّا، إذا لم نخرج إطلاقًا، نفّذ Z."
2.13.4. أنماط الحلقات الشائعة¶
تظهر بعض الأنماط كثيرًا في البرامج النصية الحقيقية:
الاستقصاء (Polling) -- الانتظار حتى يصبح شرط ما صحيحًا قبل المتابعة. يستخدم جسم الحلقة
pass، وهو تعليمة عدم العمل في Python؛ إذ يجب أن تحتوي كل كتلة مُزاحة على تعليمة واحدة على الأقل، وpassهي طريقة قول "لا تفعل شيئًا هنا":while not ready(): pass proceed()
آلة الحالة (State machine) -- حلقة
while True:واحدة تختار ما يجب فعله بناءً على متغيّر حالة. وهي مفيدة عندما ينقسم العمل بوضوح إلى عدة مراحل مُسمّاة:state = "header" for line in lines: if state == "header": if line.startswith("---"): state = "body" elif state == "body": print(line)
التراكم (Accumulating) -- بناء نتيجة أثناء السير عبر تسلسل:
total = 0 for x in samples: total += x mean = total / len(samples)
لكثير من حلقات التراكم مكافئٌ من سطر واحد باستخدام دالة مدمجة. استخدم الدالة المدمجة متى انطبقت:
sum()-- يجمع كل عنصر في كائن قابل للتكرار.any()--Trueإذا كان عنصر واحد على الأقل صحيحًا.all()--Trueفقط عندما يكون كل عنصر صحيحًا.sorted()-- قائمة جديدة بالعناصر مرتّبةً.len()-- عدد العناصر (حيث يعرف الكائن القابل للتكرار طوله).
>>> samples = [3, 1, 4, 1, 5, 9, 2, 6] >>> sum(samples) 31 >>> sum(samples) / len(samples) # mean 3.875 >>> max(samples) 9 >>> min(samples) 1 >>> sorted(samples) [1, 1, 2, 3, 4, 5, 6, 9] >>> any([False, False, True]) True >>> all([True, True, False]) False
النسخة المدمجة أقصر وأوضح وعادةً أسرع من كتابة الحلقة نفسها يدويًا.