جملة pass
جملة pass هي عملية فارغة - لا تفعل شيئاً.
تفيد كعنصر نائب عندما تحتاج جملة نحوياً لكن ليس لديك كود بعد.
Python
# pass كعنصر نائب
for ع in range(5):
pass # TODO: سيُنفذ لاحقاً
# مفيد في تعريفات الفئات/الدوال الفارغة
class فئتي:
pass # سأضيف الدوال لاحقاً
def دالتي():
pass # التنفيذ قيد الانتظار
# تجاهل حالات معينة
for رقم in range(10):
if رقم % 2 == 0:
pass # تخطي الأرقام الزوجية (لا تفعل شيئاً)
else:
print(رقم)
التحكم في الحلقات المتداخلة
break و continue تؤثر فقط على الحلقة الداخلية:
Python
# break تخرج فقط من الحلقة الداخلية
for ص in range(3):
print(f"الحلقة الخارجية: {ص}")
for س in range(3):
if س == 1:
break # تخرج فقط من الحلقة الداخلية
print(f" الحلقة الداخلية: {س}")
# الناتج:
# الحلقة الخارجية: 0
# الحلقة الداخلية: 0
# الحلقة الخارجية: 1
# الحلقة الداخلية: 0
# الحلقة الخارجية: 2
# الحلقة الداخلية: 0
# استخدام علم للخروج من الحلقة الخارجية
وجدت = False
for ص in range(5):
for س in range(5):
if ص * س == 6:
print(f"وجدت: {ص} × {س} = 6")
وجدت = True
break
if وجدت:
break
# استخدام else مع الحلقات المتداخلة
for ص in range(3):
for س in range(3):
if ص == 1 and س == 1:
break
else:
# هذا يعمل إذا لم تنكسر الحلقة الداخلية
print(f"الحلقة الداخلية اكتملت لـ ص={ص}")
continue
# هذا يعمل إذا انكسرت الحلقة الداخلية
print(f"الحلقة الداخلية انكسرت لـ ص={ص}")
الخروج من الحلقات المتداخلة
عدة تقنيات للخروج من حلقات متعددة:
Python
# الطريقة 1: استخدام دالة مع return
def ابحث_عن_هدف(مصفوفة, هدف):
for ص, صف in enumerate(مصفوفة):
for س, قيمة in enumerate(صف):
if قيمة == هدف:
return (ص, س) # تخرج من كامل الدالة
return None
مصفوفة = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
نتيجة = ابحث_عن_هدف(مصفوفة, 5)
print(f"وجدت في: {نتيجة}") # وجدت في: (1, 1)
# الطريقة 2: استخدام استثناء (للحالات المعقدة)
class اخرج_من_الحلقة(Exception):
pass
try:
for ص in range(5):
for س in range(5):
for ع in range(5):
if ص * س * ع == 24:
print(f"وجدت: {ص}, {س}, {ع}")
raise اخرج_من_الحلقة
except اخرج_من_الحلقة:
pass
# الطريقة 3: استخدام itertools.product
from itertools import product
for ص, س, ع in product(range(5), range(5), range(5)):
if ص * س * ع == 24:
print(f"وجدت: {ص}, {س}, {ع}")
break
أنماط الحلقات العملية
النمط 1: المُجمِّع
Python
# جمع الأرقام
أرقام = [1, 2, 3, 4, 5]
المجموع = 0
for رقم in أرقام:
المجموع += رقم
print(f"المجموع: {المجموع}") # 15
# بناء نص
كلمات = ["مرحباً", "بالعالم", "بايثون"]
النتيجة = ""
for كلمة in كلمات:
النتيجة += كلمة + " "
print(النتيجة.strip()) # مرحباً بالعالم بايثون
# عد التكرارات
نص = "مسيسيبي"
العد = {}
for حرف in نص:
العد[حرف] = العد.get(حرف, 0) + 1
print(العد) # {'م': 1, 'س': 2, 'ي': 3, 'ب': 1}
النمط 2: البحث والتصفية
Python
# إيجاد أول تطابق
أرقام = [3, 7, 2, 8, 1, 9, 5]
أول_زوجي = None
for رقم in أرقام:
if رقم % 2 == 0:
أول_زوجي = رقم
break
print(f"أول زوجي: {أول_زوجي}") # 2
# إيجاد جميع التطابقات
أرقام_زوجية = []
for رقم in أرقام:
if رقم % 2 == 0:
أرقام_زوجية.append(رقم)
print(f"جميع الأزواج: {أرقام_زوجية}") # [2, 8]
# باستخدام فهم القائمة
أرقام_زوجية = [رقم for رقم in أرقام if رقم % 2 == 0]
print(f"جميع الأزواج: {أرقام_زوجية}") # [2, 8]
# تصفية الكائنات
طلاب = [
{"الاسم": "أحمد", "الدرجة": 90},
{"الاسم": "سارة", "الدرجة": 55},
{"الاسم": "محمد", "الدرجة": 75},
{"الاسم": "ليلى", "الدرجة": 45}
]
الناجحون = [ط for ط in طلاب if ط["الدرجة"] >= 60]
print("الناجحون:", [ط["الاسم"] for ط in الناجحون]) # ['أحمد', 'محمد']
النمط 3: تحويل البيانات
Python
# تحويل التخطيط (Map)
أرقام = [1, 2, 3, 4, 5]
مربعات = []
for رقم in أرقام:
مربعات.append(رقم ** 2)
print(مربعات) # [1, 4, 9, 16, 25]
# باستخدام فهم القائمة
مربعات = [رقم ** 2 for رقم in أرقام]
print(مربعات) # [1, 4, 9, 16, 25]
# تحويل القاموس
أسعار = {"تفاح": 10.0, "موز": 5.0, "كرز": 20.0}
مخفضة = {}
for صنف, سعر in أسعار.items():
مخفضة[صنف] = سعر * 0.9 # خصم 10%
print(مخفضة)
# باستخدام فهم القاموس
مخفضة = {صنف: سعر * 0.9 for صنف, سعر in أسعار.items()}
print(مخفضة)
النمط 4: التكرار المتوازي
Python
# استخدام zip للتكرار المتوازي
أسماء = ["أحمد", "سارة", "محمد"]
أعمار = [25, 30, 35]
مدن = ["الرياض", "جدة", "الدمام"]
for اسم, عمر, مدينة in zip(أسماء, أعمار, مدن):
print(f"{اسم}، {عمر}، من {مدينة}")
# zip تتوقف عند الأقصر
قصيرة = [1, 2]
طويلة = [1, 2, 3, 4, 5]
for أ, ب in zip(قصيرة, طويلة):
print(أ, ب) # يطبع زوجين فقط
# zip_longest للأطوال المختلفة
from itertools import zip_longest
for أ, ب in zip_longest(قصيرة, طويلة, fillvalue=0):
print(أ, ب) # يطبع 5 أزواج، يملأ بـ 0
# إنشاء قاموس من قائمتين
مفاتيح = ["الاسم", "العمر", "المدينة"]
قيم = ["أحمد", 25, "الرياض"]
شخص = dict(zip(مفاتيح, قيم))
print(شخص) # {'الاسم': 'أحمد', 'العمر': 25, 'المدينة': 'الرياض'}
النمط 5: النافذة المنزلقة
Python
# معالجة أزواج متتالية
أرقام = [1, 2, 3, 4, 5]
for ع in range(len(أرقام) - 1):
الحالي = أرقام[ع]
التالي = أرقام[ع + 1]
print(f"{الحالي} -> {التالي}")
# باستخدام zip للأزواج
for الحالي, التالي in zip(أرقام, أرقام[1:]):
print(f"{الحالي} -> {التالي}")
# المتوسط المتحرك (نافذة من 3)
بيانات = [10, 20, 30, 40, 50, 60, 70]
حجم_النافذة = 3
متوسطات = []
for ع in range(len(بيانات) - حجم_النافذة + 1):
نافذة = بيانات[ع:ع + حجم_النافذة]
متوسط = sum(نافذة) / حجم_النافذة
متوسطات.append(متوسط)
print(f"المتوسطات المتحركة: {متوسطات}")
# [20.0, 30.0, 40.0, 50.0, 60.0]
نصائح أداء الحلقات
Python
# النصيحة 1: انقل الحسابات خارج الحلقة
قائمة = list(range(1000))
# سيء
for ع in range(1000):
نتيجة = len(قائمة) * ع # len() تُستدعى 1000 مرة
# جيد
طول_القائمة = len(قائمة)
for ع in range(1000):
نتيجة = طول_القائمة * ع # len() تُستدعى مرة واحدة
# النصيحة 2: استخدم هياكل البيانات المناسبة
# سيء - O(n) بحث في كل مرة
عناصر = [1, 2, 3, 4, 5]
for ع in range(1000):
if ع in عناصر: # بحث خطي
pass
# جيد - O(1) بحث
مجموعة_عناصر = {1, 2, 3, 4, 5}
for ع in range(1000):
if ع in مجموعة_عناصر: # بحث بالتجزئة
pass
# النصيحة 3: استخدم الدوال المدمجة
أرقام = list(range(10000))
# أبطأ
المجموع = 0
for رقم in أرقام:
المجموع += رقم
# أسرع
المجموع = sum(أرقام)
# النصيحة 4: فهم القائمة vs الحلقة
# أبطأ قليلاً (استدعاء دالة)
نتيجة = []
for س in range(1000):
نتيجة.append(س ** 2)
# أسرع
نتيجة = [س ** 2 for س in range(1000)]
متى تُحسِّن
لا تُحسِّن قبل الأوان! اكتب كوداً واضحاً وقابلاً للقراءة أولاً. حسِّن فقط عندما تحدد عنق زجاجة في الأداء من خلال التحليل.
تحدي: مُدقق كلمة المرور
اكتب دالة تتحقق من صحة كلمة المرور:
- 8 أحرف على الأقل
- تحتوي على حرف كبير واحد على الأقل
- تحتوي على حرف صغير واحد على الأقل
- تحتوي على رقم واحد على الأقل
- تحتوي على رمز خاص واحد على الأقل (!@#$%^&*)
أظهر الحل
def تحقق_كلمة_السر(كلمة_السر):
# تحقق من الطول
if len(كلمة_السر) < 8:
return False, "كلمة السر يجب أن تكون 8 أحرف على الأقل"
لديه_كبير = False
لديه_صغير = False
لديه_رقم = False
لديه_خاص = False
الرموز_الخاصة = "!@#$%^&*"
for حرف in كلمة_السر:
if حرف.isupper():
لديه_كبير = True
elif حرف.islower():
لديه_صغير = True
elif حرف.isdigit():
لديه_رقم = True
elif حرف in الرموز_الخاصة:
لديه_خاص = True
# تحقق من جميع المتطلبات
if not لديه_كبير:
return False, "ينقص حرف كبير"
if not لديه_صغير:
return False, "ينقص حرف صغير"
if not لديه_رقم:
return False, "ينقص رقم"
if not لديه_خاص:
return False, "ينقص رمز خاص"
return True, "كلمة السر صالحة"
# اختبار
كلمات_سر = ["ضعيف", "StrongPass1!", "NoSpecial1", "nouppercase1!"]
for كلمة in كلمات_سر:
صالح, رسالة = تحقق_كلمة_السر(كلمة)
print(f"{كلمة}: {رسالة}")
تحدي: عمليات المصفوفة
أنشئ دوال لـ:
- إيجاد مجموع جميع العناصر في مصفوفة
- إيجاد أكبر عنصر وموقعه
- تبديل صفوف المصفوفة بأعمدتها
أظهر الحل
def مجموع_المصفوفة(مصفوفة):
المجموع = 0
for صف in مصفوفة:
for قيمة in صف:
المجموع += قيمة
return المجموع
def ابحث_عن_الأكبر(مصفوفة):
أكبر_قيمة = مصفوفة[0][0]
موقع_الأكبر = (0, 0)
for ص, صف in enumerate(مصفوفة):
for س, قيمة in enumerate(صف):
if قيمة > أكبر_قيمة:
أكبر_قيمة = قيمة
موقع_الأكبر = (ص, س)
return أكبر_قيمة, موقع_الأكبر
def التبديل(مصفوفة):
الصفوف = len(مصفوفة)
الأعمدة = len(مصفوفة[0])
النتيجة = []
for س in range(الأعمدة):
صف_جديد = []
for ص in range(الصفوف):
صف_جديد.append(مصفوفة[ص][س])
النتيجة.append(صف_جديد)
return النتيجة
# اختبار
مصفوفة = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(f"المجموع: {مجموع_المصفوفة(مصفوفة)}") # 45
print(f"الأكبر: {ابحث_عن_الأكبر(مصفوفة)}") # (9, (2, 2))
print(f"التبديل: {التبديل(مصفوفة)}")
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
النقاط الرئيسية
ملخص
passعنصر نائب لا يفعل شيئاًbreakوcontinueتؤثر فقط على الحلقة الداخلية- استخدم الدوال أو الأعلام للخروج من الحلقات المتداخلة
- الأنماط الشائعة: المُجمِّع، البحث/التصفية، التحويل، التكرار المتوازي
- استخدم
zip()للتكرار المتوازي على تسلسلات متعددة - فهم القوائم غالباً أسرع من الحلقات التقليدية
- حسِّن فقط بعد تحديد عنق الزجاجة الفعلي
في الدرس القادم، سنستكشف هياكل البيانات بدءاً بالقوائم!