الحلقات التكرارية في بايثون: for وwhile

45 دقيقة تقريبًا

ما تحتاج أن تعرفه قبل هذا الدرس
  • variable
  • string
  • list
  • dictionary
  • if
  • print
  • comparison
  • set
ما يضيفه هذا الدرس
  • for
  • in
  • iteration
  • indentation
  • range
  • while
  • break
  • continue
  • endswith

يحسب العدّاد في الأعلى تمارين الدرس، وعددها 15، أما القراءة وتشغيل الأمثلة فلا تُحتسب.

قبل ما ندخل في الكود، خلينا نفهم المشكلة اللي الـ Loops بتحلها.

تخيل إن عندك 4 روابط:

مثال
الناتج المتوقع
https://example.com/page1
https://example.com/page2
https://example.com/page3
https://example.com/page4

الكود شغال، لكن المشكلة إنك كتبت print() أربع مرات.

لو عندك 10,000 URL، هل هتكتب print() عشرة آلاف مرة؟

طبعًا لا.

هنا تظهر فكرة Loop.

القاعدة
الـ Loop معناها ببساطة: كرر نفس العملية أكثر من مرة.

لكن التكرار ممكن يحصل بطريقتين مختلفتين، وده السبب إن عندنا for وعندنا while.

أولًا: for

الـ Mindset

استخدم for لما يكون عندك مجموعة من العناصر وعايز تعمل حاجة على كل عنصر فيها.

مثال بسيط:

دي List فيها 3 أسماء.

عايز أطبع كل اسم.

بدل ما أكتب:

الطريقة اليدوية
الناتج المتوقع
Islam
Ahmed
Ali

أقدر أستخدم:

مثال
الناتج المتوقع
Islam
Ahmed
Ali

دلوقتي نفهم الكود كلمة كلمة.

ما معنى for؟

لما تكتب:

تقدر تقرأها بالعربي:

القاعدة
لكل اسم موجود داخل names، نفذ الكود الموجود أسفل for.

for هنا معناها إن Python هيمر على العناصر واحدًا واحدًا.

ما معنى in؟

in هنا معناها: داخل.

إذن:

تقريبًا معناها: لكل name داخل names.

من أين جاءت name؟

عندنا القائمة:

ولما كتبنا:

إحنا أنشأنا متغير اسمه name.

Python هيضع فيه عنصرًا واحدًا من القائمة في كل مرة.

اللي بيحصل في كل مرة
  • name = "Islam"في أول مرة، وينفذ print(name) فتظهر Islam
  • name = "Ahmed"في المرة الثانية، فتظهر Ahmed
  • name = "Ali"في المرة الثالثة، فتظهر Ali

إذن الكود:

يمكن تخيله داخليًا كأنه:

نفس الكود لو فكّكناه بإيدنا
الناتج المتوقع
Islam
Ahmed
Ali

والناتج في الحالتين واحد.

ملحوظة
الفرق إن الـ for عملت التكرار بدل منك.

ما معنى Iteration؟

هتقابل مصطلح مهم اسمه Iteration.

القاعدة
الـ Iteration معناها: دورة واحدة من الـ Loop.

في الكود:

عندنا 3 Iterations.

  • name = "Islam"الدورة الأولى
  • name = "Ahmed"الدورة الثانية
  • name = "Ali"الدورة الثالثة

إذن لو عندك 100 عنصر، غالبًا الـ for ستعمل 100 Iterations.

هل لازم أسمي المتغير name؟

لا.

الكود ده صحيح:

جرّب بنفسك — غيّر وشغّل
الناتج المتوقع
Islam
Ahmed
Ali

وده كمان صحيح:

جرّب بنفسك — غيّر وشغّل
الناتج المتوقع
Islam
Ahmed
Ali

لكن الأفضل تختار اسمًا يوضح نوع العنصر.

لو عندك:

الأفضل:

مثال
الناتج المتوقع
/home
/about
/contact

بدل:

ملحوظة
الاتنين صحيحين، لكن url أوضح.

الـ Indentation مع for

الـ Indentation هنا أساسية جدًا.

شوف المثال:

مثال
الناتج المتوقع
Islam
Ahmed
Ali
Finished

ليه Finished ظهرت مرة واحدة؟

لأن print("Finished") ليست داخل الـ for. لاحظ إنها بدأت من أول السطر.

لكن لو كتبنا:

مثال
الناتج المتوقع
Islam
Finished
Ahmed
Finished
Ali
Finished

ليه؟ لأن print(name) و print("Finished") الاتنين داخل الـ for.

القاعدة
إذن الـ Indentation بتحدد: إيه الكود اللي هيتكرر؟

ودي قاعدة مهمة جدًا.

أول تطبيق SEO باستخدام for

عندنا URLs:

جرّب تغيّر القائمة وشغّل
الناتج المتوقع
/home
/about
/services
/contact

اللي حصل:

  • url = "/home"Iteration 1
  • url = "/about"Iteration 2
  • url = "/services"Iteration 3
  • url = "/contact"Iteration 4

إذن لو عندك List فيها URLs، الـ for تقدر تمر عليها واحدة واحدة.

دمج for مع if

الآن نبدأ نجمع الدروس مع بعضها.

عندنا Status Codes:

نريد طباعة الأكواد التي ليست 200.

نكتب:

مثال
الناتج المتوقع
404
500

تعالى نمشي دورة دورة.

الدورة الأولى

status = 200. الشرط status != 200 يعني 200 != 200، والنتيجة False.

إذن لا يتم تنفيذ print(status).

الدورة الثانية

status = 404. الشرط يصبح 404 != 200، وده True.

إذن print(status) تطبع 404.

الدورة الثالثة

status = 200. الشرط False، فلا تتم الطباعة.

الدورة الرابعة

status = 500. الشرط 500 != 200 يعني True، فتطبع 500.

وعشان كده الناتج النهائي هو 404 و 500.

استخدام List فيها Dictionaries

دلوقتي ناخد شكل بيانات أقرب للشغل الحقيقي.

إحنا عندنا هنا List. داخل الـ List عندنا Dictionaries.

نجرب الأول:

مثال
الناتج المتوقع
{'url': '/home', 'status': 200}
{'url': '/about', 'status': 404}
{'url': '/services', 'status': 200}
{'url': '/contact', 'status': 500}

ليه؟ لأن المتغير page في كل Iteration يحتوي على Dictionary كاملة.

  • page = {"url": "/home", "status": 200}أول دورة
  • page = {"url": "/about", "status": 404}ثاني دورة
  • …وهكذا

طباعة الـ URL فقط

لو عايز قيمة url الموجودة داخل كل Dictionary:

جرّب بنفسك — غيّر وشغّل
الناتج المتوقع
/home
/about
/services
/contact

ليه كتبنا page["url"]؟ لأن page نفسها Dictionary.

مثلًا في أول Iteration page تساوي {"url": "/home", "status": 200}، وعندما نكتب page["url"] نحصل على /home.

طباعة الصفحات التي بها مشكلة فقط

الآن نجمع: List + Dictionary + for + if.

الكود:

مثال
الناتج المتوقع
/about
/contact

ليه؟

  1. 1أول صفحة {"url": "/home", "status": 200}. الشرط 200 != 200 يعني False. لا يتم طباعة شيء.
  2. 2ثاني صفحة {"url": "/about", "status": 404}. الشرط 404 != 200 يعني True. فتتم طباعة /about.
  3. 3ثالث صفحة Status الخاص بها 200، فلا تتم طباعتها.
  4. 4رابع صفحة Status الخاص بها 500، فتتم طباعة /contact.

ثانيًا: range()

أحيانًا لا يكون عندك List تريد المرور عليها، لكن عايز تعمل شيء عددًا معينًا من المرات.

هنا نستخدم range().

مثال:

مثال
الناتج المتوقع
0
1
2
3
4
خد بالك
مهم جدًا تلاحظ حاجة: range(5) لم تطبع 5. لأن range(5) تبدأ من صفر، وتتوقف قبل 5.

تحديد البداية والنهاية

ممكن تكتب:

جرّب بنفسك — غيّر وشغّل
الناتج المتوقع
1
2
3
4
5

ليه؟ لأن range(1, 6) تعني: ابدأ من 1 وتوقف قبل 6.

القاعدة
إذن القاعدة: range(start, stop) — والـ stop لا تدخل في الناتج.

إضافة Step

ممكن نكتب:

جرّب بنفسك — غيّر وشغّل
الناتج المتوقع
0
2
4
6
8

القيم هنا معناها: range(0, 10, 2) يعني ابدأ من 0، توقف قبل 10، تحرك كل مرة بمقدار 2.

فتكون الحركة
  • 0
  • 2
  • 4
  • 6
  • 8
  • 10الرقم التالي، لكننا نتوقف قبل 10

ثالثًا: while

الـ Mindset

for تقول: عندي مجموعة عناصر، لف عليها.

لكن while تقول: استمر في التكرار طالما الشرط True.

يعني while لا تعتمد أساسًا على List، بل على Condition.

مثال بسيط:

مثال
الناتج المتوقع
1
2
3
4
5

تعالى نفهم ده بهدوء.

البداية

كتبنا number = 1. إذن حاليًا number تساوي 1.

بعدها while number <= 5 — Python تسأل: هل 1 أصغر من أو يساوي 5؟ الإجابة True، فتدخل داخل الـ while.

الدورات واحدة واحدة
  • 1 <= 5 → Trueتطبع 1، ثم number = 2
  • 2 <= 5 → Trueتطبع 2، ثم number = 3
  • 3 <= 5 → Trueتطبع 3، ثم number = 4
  • 4 <= 5 → Trueتطبع 4، ثم number = 5
  • 5 <= 5 → Trueتطبع 5، ثم number = 6
  • 6 <= 5 → Falseفتتوقف

إذن الناتج النهائي: 1 و 2 و 3 و 4 و 5.

لماذا number = number + 1 مهمة؟

لو حذفناها:

الكود ده مش هيقف — متشغّلوش
الناتج
1
1
1
1
1
1
1
1
...

ماذا سيحدث؟ في البداية number = 1، والشرط 1 <= 5 يعني True، فتطبع 1. لكن number لم تتغير.

فتعود while وتسأل مرة أخرى 1 <= 5 — ما زالت True. فتطبع 1، ثم تعود مرة أخرى. وتستمر بلا نهاية.

خد بالك
وده اسمه Infinite Loop — يعني Loop لا تنتهي.

إذن مع while اسأل نفسك دائمًا: ما الذي سيحدث داخل الـ Loop ويجعل الشرط يتحول في النهاية من True إلى False؟

في مثالنا number = number + 1 هي التي غيرت قيمة number.

ملحوظة
لو جرّبت تشغّل Loop مالهاش نهاية في أي بلوك هنا، الصفحة هتوقفها بعد ١٠ ثواني وتقول لك TimeoutError بدل ما التاب يعلّق.

الفرق الأساسي بين for و while

احفظ المنطق، وليس الكود.

for

عندي مجموعة عناصر وعايز أعمل حاجة على كل عنصر.

مثال SEO: for url in urls: يعني مر على كل URL.

while

عايز أكرر حاجة طالما شرط معين متحقق.

مثال: while attempts < 3: يعني استمر طالما عدد المحاولات أقل من 3.

رابعًا: break

قبل الكود، نفهم الـ Mindset.

القاعدة
break معناها: أوقف الـ Loop الحالية بالكامل الآن.

مثال:

مثال
الناتج المتوقع
1
2

ليه لم يظهر 3 و 4 و 5؟ نمشي عليها.

  • number = 11 == 3 يعني False، فتطبع 1
  • number = 2الشرط False، فتطبع 2
  • number = 33 == 3 يعني True، فيتم تنفيذ break
  • number = 4لم نصل إليها
  • number = 5لم نصل إليها

break يعني: اخرج من الـ for فورًا. وبالتالي لا تصل إلى 4 و 5.

ولا يتم طباعة 3 نفسها، لأن break حدثت قبل print(number).

خامسًا: continue

الـ continue مختلفة.

القاعدة
لا توقف الـ Loop، فقط تجاهل الـ Iteration الحالية وانتقل للعنصر التالي.

مثال:

مثال
الناتج المتوقع
1
2
4
5

لاحظ إن 3 فقط اختفت. لكن 4 و 5 تم تنفيذهم عادي.

ليه؟ عندما number = 3 تم تنفيذ continue، ومعناها: خلاص، سيب باقي كود الـ Iteration الحالية وروح للـ Iteration التالية.

فالـ print() لم تعمل مع 3. لكن الـ Loop لم تتوقف — انتقلت إلى number = 4 ثم number = 5.

الفرق بين break و continue

شوف المثالين جنب بعض.

break

الناتج
1
2

معناها: عند 3، وقف الـ Loop كلها.

continue

الناتج
1
2
4
5

معناها: تجاهل 3 فقط وكمل.

القاعدة
break = وقف الـ Loop. continue = تجاهل الدورة الحالية فقط.

مثال SEO على continue

عندنا:

نفترض إننا لا نريد معالجة الصور. نكتب:

جرّب بنفسك — غيّر وشغّل
الناتج المتوقع
/home
/about
/contact

مهم، استخدمنا هنا endswith() ومعناها ببساطة: هل النص ينتهي بشيء معين؟

جرّبها لوحدها
الناتج المتوقع
True

لذلك عند الصور تم تنفيذ continue فتم تجاهلها.

Mindset سريع قبل المثال النهائي

دلوقتي عندنا أربع أفكار.

  • forعندي مجموعة عناصر، لف عليها
  • whileكرر طالما الشرط True
  • continueتجاهل العنصر الحالي وكمل
  • breakوقف الـ Loop الحالية بالكامل

دلوقتي هنضع الأربعة في مثال واحد. وده أهم مثال في الدرس.

المثال النهائي: for + while + continue + break

عندنا الكود:

أهم مثال في الدرس — شغّله وقارن بالتتبّع تحت
الناتج المتوقع
/home
/about
/home
/about
/home
/about

دلوقتي هنفكك المثال بالكامل.

أولًا: البيانات

دي List فيها 5 عناصر. بعدها:

يعني عدد المحاولات يبدأ بصفر.

أين تتبع attempts = attempts + 1؟

بص على الـ Indentation:

السطر attempts = attempts + 1 داخل الـ while. إذن هو تابع للـ while. لكنه ليس داخل الـ for.

لاحظ المستوى: while attempts < 3: وداخلها for url in urls:، وكل ما هو داخل for يأخذ Indentation إضافية مثل print(url). لكن attempts = attempts + 1 رجعنا مستوى للخلف.

القاعدة
إذن معناه: بعد ما الـ for تخلص أو تتوقف، زود attempts بمقدار 1.

نبدأ التنفيذ

في البداية attempts = 0. الـ while تختبر 0 < 3، والنتيجة True. إذن ندخل أول محاولة.

المحاولة الأولى

الـ for تبدأ من أول عنصر في List. وده مهم جدًا.

خد بالك
كل مرة الـ while تعيد تشغيل الكود، الـ for الجديدة تبدأ من أول الـ List، ولا تكمل من المكان الذي توقفت عنده في المحاولة السابقة.
المحاولة الأولى
  • url = "/home"مش صورة، ومش /stop — فتطبع /home
  • url = "/image.jpg"endswith(.jpg) يعني True، فـ continue
  • url = "/about"مش صورة، ومش /stop — فتطبع /about
  • url = "/stop"الشرط True، فـ break
  • url = "/contact"لم نصل إليها
  • attempts = 1بعد ما الـ for وقفت

إذن لا نصل إلى print(url) مع /image.jpg، ولذلك لا تظهر في النتيجة.

والـ break معناها: أوقف الـ for الحالية بالكامل. إذن لن تصل الـ for إلى العنصر التالي /contact. وده سبب مهم جدًا في إن /contact لا تظهر نهائيًا.

نخرج من الـ for لكننا ما زلنا داخل الـ while، فنصل إلى attempts = attempts + 1. وكانت attempts = 0 فتصبح attempts = 1.

المحاولة الثانية

الـ while تعود وتختبر 1 < 3 يعني True. إذن تبدأ دورة جديدة.

وهنا نقطة مهمة جدًا: الـ for الموجودة داخلها تبدأ مرة أخرى من /home وليس من /contact. ليه؟ لأن دي for جديدة بدأت من أول القائمة.

المحاولة الثانية — نفس المسار بالظبط
  • url = "/home"تطبع /home
  • url = "/image.jpg"continue
  • url = "/about"تطبع /about
  • url = "/stop"break
  • attempts = 2

المحاولة الثالثة

الـ while تسأل 2 < 3 يعني True. إذن تبدأ مرة ثالثة، والـ for تبدأ مرة أخرى من أول عنصر.

المحاولة الثالثة
  • url = "/home"تطبع /home
  • url = "/image.jpg"continue
  • url = "/about"تطبع /about
  • url = "/stop"break
  • attempts = 3

هل توجد محاولة رابعة؟

الـ while ترجع لاختبار الشرط 3 < 3، والنتيجة False. إذن تتوقف.

لهذا حصلنا على 3 محاولات فقط.

القيم التي حققت الشرط
  • 0 < 3 → Trueالمحاولة الأولى
  • 1 < 3 → Trueالمحاولة الثانية
  • 2 < 3 → Trueالمحاولة الثالثة
  • 3 < 3 → Falseتوقف

لماذا /contact لم تظهر ولا مرة؟

لأن ترتيب القائمة هو /home ثم /image.jpg ثم /about ثم /stop ثم /contact. وفي كل محاولة، عندما تصل الـ for إلى /stop يتم تنفيذ break فتنتهي الـ for.

إذن لم تصل أصلًا إلى /contact. ولا في المحاولة الأولى، ولا الثانية، ولا الثالثة.

لماذا /image.jpg لم تظهر؟

لأن continue جعلت Python تتخطى هذه الـ Iteration فقط. يعني /image.jpg تم الوصول إليها، لكن تم تجاهلها.

أما /contact فالوضع مختلف: Python لم تصل إليها أصلًا بسبب break.

القاعدة
/image.jpg تم الوصول إليها ثم تجاهلها. contact لم يتم الوصول إليها أصلًا.

الفرق بين continue و break داخل المثال

عند /image.jpg حدث continue، فكان المعنى: سيب العنصر ده وروح للعنصر اللي بعده. فانتقلنا إلى /about.

لكن عند /stop حدث break، فكان المعنى: وقف الـ for كلها. لذلك لم ننتقل إلى /contact.

Mindset الدرس بالكامل

لو قابلتك مشكلة وعايز تعرف تستخدم إيه، فكر هكذا.

عندي مجموعة بيانات

مثل URLs أو Keywords أو Status Codes أو Pages، وعايز أمر عليها واحدة واحدة؟ استخدم for.

عايز التكرار يستمر بناءً على شرط؟

مثل: استمر طالما attempts أقل من 3. استمر طالما فيه صفحة تالية. استمر طالما API ما زالت ترجع بيانات. استخدم while.

أنا داخل Loop وعايز أتجاهل العنصر الحالي فقط؟

مثل: لقيت صورة ومش عايز أحلل الصور. استخدم continue.

أنا داخل Loop وعايز أوقفها تمامًا؟

مثل: وصلت للحد الأقصى. وجدت العنصر الذي أبحث عنه. وصلت إلى قيمة معينة وأريد إنهاء العملية. استخدم break.

الاختبار

ملحوظة
مهم، هنا لن أضع النتائج، لأن المطلوب منك أنت تتوقع النتيجة. اكتب توقّعك الأول، وبعد ما تجاوب هيتشغّل الكود الحقيقي وتقارن بنفسك.

السؤال الأول

جاوب بأسلوبك

اشرح بأسلوبك الفرق بين for و while و continue و break. ولا أريد تعريفات محفوظة، أريد الـ Mindset بتاعتك لكل واحدة.

اكتب إجابتك الأول. الفايدة في إنك تحاول قبل ما تشوف.

السؤال الثاني

توقّع الناتج

ما الناتج؟

السؤال الثالث

اختبر فهمك

كم Iteration ستحدث في الكود ده؟ وما قيمة url في كل Iteration؟

كود السؤال الثالث

السؤال الرابع

توقّع الناتج

ما الناتج؟

السؤال الخامس

توقّع الناتج

ما الناتج؟

السؤال السادس

توقّع الناتج

ما الناتج؟

اختبر فهمك

ولماذا لم يظهر الرقم 5؟

السؤال السابع

توقّع الناتج

ما الناتج؟

السؤال الثامن

توقّع الناتج

ما الناتج؟ واشرح لنفسك قيمة number في كل دورة.

السؤال التاسع

الكود ده مش هيقف — متشغّلوش
اختبر فهمك

ما المشكلة في الكود ده؟ وما اسم المشكلة التي ستحدث؟

السؤال العاشر

توقّع الناتج

ما الناتج؟ واشرح لنفسك لماذا لم يظهر رقم معين.

السؤال الحادي عشر

توقّع الناتج

ما الناتج؟ واشرح لنفسك لماذا لم تظهر الأرقام الموجودة بعد 3.

السؤال الثاني عشر، أهم سؤال

تحدّي SEO

اطبع الـ URLs التي الـ Status Code الخاص بها ليس 200

اكتب كود يستخدم for و if لطباعة الـ URLs التي الـ Status Code الخاص بها ليس 200.

السؤال الثالث عشر، تحدي الدرس

بدون تشغيل الكود، توقع الناتج بالكامل:

توقّع الناتج

توقّع الناتج بالكامل قبل ما تشغّل.

اختبر فهمك

كم محاولة ستحدث؟ ولماذا image.jpg و contact لم تظهرا؟

لو جاوبت على الأسئلة دي كلها وفهمت ليه /contact مظهرتش ولا مرة، يبقى انت فاهم الـ Loops فعلاً — مش حافظ شكلها.

بقيت تمارين لم تحلّها

0/15

التمارين المتبقية: 15 من 15. يُحتسب الدرس مكتملًا حين تحلّها كلها، ويمكنك العودة إليها متى شئت.

أحسنت، وصلت إلى نهاية الدرس.