1.3الحلقات (for وwhile) والاستيعابات
الأساسي في 30 ثانية
- تجول for أشياء : for nom in eleves: — دون مؤشرات على الطريقة C ؛ وenumerate() إن كان المؤشر مهما، وrange() للعدّ.
- while = ما دام، مع خروج : يجب أن يتطور الشرط (عدّاد، break) — وإلا حلقة لانهائية، يقطعها Ctrl+C.
- الاستيعاب = حلقة بسيطة في سطر واحد : [x*x for x in nombres if x > 0] — محجوز للبسيط، والحلقة الكلاسيكية لما بعده.
حالة مستمرة — نبيل يجول مجيبيه في الجزائر
على نبيل تحية كل مجيب، وإعادة طلب رمز حتى يكون صالحا، ثم استخراج مربعات الدرجات الموجبة. فكتب أولا for i in range(len(noms)) بخطأ مؤشر، ثم while True دون break تدور دون نهاية. فصحح : for nom in noms مباشرة، وwhile بعدّاد يتناقص، واستيعاب بسيط للمربعات. فخرج التقرير في تمريرة واحدة دون حلقة لانهائية.
تتمة الحالة 1.1-1.2 — ينتقل نبيل من القرارات إلى التكرار.
1. for : جُل ولا تعُدّ
في Python نكرر على أشياء (for nom in eleves:) وليس على مؤشرات : فـ for بالمؤشرات على الطريقة C علامة أننا نحارب اللغة. تحتاج مؤشرات ؟ enumerate() ؛ وتحتاج العدّ ؟ range() (تعطي range(5) من 0 إلى 4). تخرج break من الحلقة، وتتجاوز continue دورا.
يستبدل نبيل for i in range(len(noms)) بـ for nom in noms: ويحتفظ بـ enumerate() لترقيم التقرير : فانتهى خطأ المؤشر.
2. while والاستيعابات
تكرر while ما دام الشرط صادقا (مدخل مستخدم، انتظار) : فاضمن الخروج (عدّاد يتطور، break). ويُرشّح استيعاب القائمة (list comprehension) [expression for x in sequence if condition] ويحوّل بمقروئية في سطر واحد — محجوز للبسيط (شرط واحد وتعبير واحد)، وإلا فالحلقة الكلاسيكية تكسب.
يكتب نبيل while tentatives > 0: بتناقص، ثم [s**2 for s in scores if s > 0] للمربعات الموجبة : فتنتهي إعادة الطلب، ويتسع الاستخراج في سطر واحد.
while دون خروج (لا تفعل هذا أبدا)
العبرة : حلقة دون خروج كهامستر في عجلته — مشغول جدا، ولم يصل أبدا.
🔎 مثال ملموس — 🔎 مثال ملموس — ثلاث طرق وخيار واحد صحيح لكل واحدة
لكل حلقة إقليمها، كما فعل نبيل في تقريره.
for nom in ["ياسمين", "نبيل"]:
print(f"مرحبا {nom}")
tentatives = 3
while tentatives > 0:
tentatives -= 1
carres = [x * x for x in range(10)]
print(carres) # [0, 1, 4, ..., 81]
القراءة : for مباشرة على العناصر، وwhile بعدّاد يتطور، واستيعاب لبناء القائمة.
الدرس : enumerate() حين يكون المؤشر مهما حقا — وليس range(len()) بالمنعكس أبدا.
مفردات القسم
- الحلقة for
- تكرر كتلة لكل عنصر من متتالية : for x in sequence. نَجول أشياء لا مؤشرات.
مثال بسيط: المجيبون الذين حياهم نبيل واحدا واحدا.
ما ليس كذلك: for i in range(len(x)) منهجية مع x[i].
رد فعل: for مباشرة ؛ وenumerate() إن كان المؤشر مهما.
- range()
- تولّد مجال أعداد : تعطي range(5) الأعداد 0 و1 و2 و3 و4. شائعة جدا مع for للعدّ أو التكرار N مرة.
مثال بسيط: مربعات 0 إلى 9 التي حسبها نبيل.
ما ليس كذلك: range(len(liste)) لاسترجاع العناصر.
رد فعل: range() للعدّ وليس للفهرسة.
- الحلقة while
- تكرر كتلة ما دام الشرط صادقا. وخطر الحلقة اللانهائية إن لم يتغير الشرط أبدا — فاضمن الخروج.
مثال بسيط: إعادة طلب نبيل للرمز حتى مدخل صالح.
ما ليس كذلك: while True دون break ودون شرط يتطور.
رد فعل: عدّاد أو break أو متغير يتغير كل دور.
- break / continue
- تخرج break من الحلقة فورا ؛ وتتجاوز continue مباشرة إلى التكرار التالي.
مثال بسيط: break نبيل فور إدخال الرمز الصحيح.
ما ليس كذلك: ترك تجوال القائمة كلها وقد وُجد الهدف.
رد فعل: break للإيقاف وcontinue للتجاوز.
- استيعاب القائمة
- كتابة مضغوطة : [expression for x in sequence if condition] تبني قائمة في سطر واحد، على الطريقة Pythonية.
مثال بسيط: مربعات الدرجات الموجبة التي استخرجها نبيل.
ما ليس كذلك: استيعاب متداخل غير مقروء على ثلاثة مستويات.
رد فعل: البسيط = استيعاب ؛ والمعقد = حلقة كلاسيكية.
في التطبيق — تطبيقيا — كرر بـ for وwhile والاستيعابات
- اعرض الأعداد من 1 إلى 10 بـ « for i in range(1, 11) » ثم مربعها. وأضف جدول ضرب عدد مدخل.
- اكتب حلقة while تعيد طلب كلمة سر حتى تكون صحيحة (واحرص على تطور الشرط).
- استعمل break لإيقاف حلقة فور وقوع شرط، وcontinue لتجاوز الأعداد الزوجية.
- حوّل حلقة تبني قائمة مربعات إلى استيعاب قائمة : carres = [n**2 for n in range(10)]. وقارن المقروئية.
نص جاهز للنطق — اقترح for المباشرة (30 ث)
« أقترح أن نكرر مباشرة على العناصر بدلا من المؤشرات : for nom in noms — فهو أمقروء ويلغي خطأ المؤشر. ونحتفظ بـ enumerate() فقط إن كان الرقم يفيدنا حقا. »
يُقال في مراجعة الشيفرة ؛ واعرض قبل/بعد على الحلقة الحقيقية.
نموذج نسخ ولصق — for مباشرة وwhile بخروج واستيعاب
noms = ["ياسمين", "كريم", "لينا"]
for i, nom in enumerate(noms, start=1):
print(f"{i}. مرحبا {nom}")
tentatives = 3
while tentatives > 0:
code = input("الرمز ؟ ")
if code == "ALGER":
print("الرمز مقبول")
break
tentatives -= 1
carres_positifs = [s ** 2 for s in [3, -1, 4] if s > 0]
print(carres_positifs) # [9, 16]
تقرير في الجزائر
كما فعل نبيل : for مباشرة + enumerate(start=1) — كل مجيب مُحيَّى ومرقم، وصفر خطأ مؤشر.
إعادة مضمونة
while بعدّاد يتناقص وbreak عند النجاح : فينتهي المدخل دائما.
استخراج في سطر واحد
استيعاب بسيط للدرجات الموجبة : ترشيح + تحويل بمقروئية، دون حلقة من 5 أسطر.
تجاوز مستهدف
continue لتجاهل الزوجيات : نتجاوز دورا بدلا من تداخل if — فيبقى التدفق مسطحا.
✓ ممارسات جيدة
- كرر على الأشياء (for مباشرة)، وenumerate() إن كان المؤشر يفيد.
- اضمن خروج كل while (عدّاد، break، شرط يتطور).
- احجز الاستيعاب للبسيط، والحلقة الكلاسيكية لغيره.
✗ أخطاء شائعة
- كتابة for i in range(len(x)) منهجيا.
- إطلاق while True دون break (حلقة لانهائية).
- تكديس استيعابات متداخلة غير مقروءة.
النقاط الأساسية
- تجول for متتالية ؛ وتكرر while ما دام شرط صادقا.
- تولّد range() مجالات الأعداد ؛ وتعطي enumerate() المؤشر + القيمة.
- تخرج break من الحلقة ؛ وتتجاوز continue إلى التكرار التالي.
- تبني استيعابات القوائم قائمة في سطر واحد، على الطريقة Pythonية — للبسيط.
تحدي 48 ساعة — طبّق غدا
حوّل حلقة for + range(len()) إلى for مباشرة (النموذج أعلاه)، وأضف خروجا مضمونا إلى while، واضغط بناء قائمة في استيعاب بسيط. وقارن قبل/بعد محليا. تكفي 20 دقيقة.
- أَجول بـ for مباشرة — وenumerate() فقط إن كان المؤشر يفيد.
- لـ while خروج مضمون وbreak/continue في موضعهما.
- أكتب استيعابات بسيطة مقروءة.
أسئلة شائعة
متى تختار for بدلا من while ؟
استعمل for حين تعرف ما تجوله (قائمة أو مجال أو ملف). واستعمل while حين تكرر حتى شرط تجهل مسبقا عدد تكراراته (مثلا « ما دام المستخدم لم يغادر ») — مع ضمان الخروج.
حلقة while تدور دون نهاية، لماذا ؟
فهي حلقة لانهائية : يبقى الشرط صادقا دائما لأن لا شيء يجعله يتطور في الكتلة. فتأكد أن متغيرا من الشرط يتغير كل دور (عدّاد، break). ويقطع Ctrl+C برنامجا محجوبا.
أي كتابة تُفضَّل لتجوال قائمة ؟