Menu
العربية

دالة range() في بايثون: البداية والنهاية والخطوة

شرح عملي لدالة range() في بايثون: معاملات البداية والنهاية والخطوة، العد التنازلي بخطوة سالبة، ولماذا لا ترجع قائمة فعلية.

دالة range في بايثون: أداة لتوليد الأرقام

تقوم دالة range() بمهمة واحدة فقط: توليد سلسلة من الأعداد الصحيحة. وهي الرفيق المثالي لحلقة for في بايثون عندما تحتاج إلى تكرار عملية عددًا محددًا من المرات، أو المرور على مجال رقمي معيّن.

أبسط صيغة لها تأخذ وسيطًا واحدًا فقط، وهو قيمة التوقف (stop):

main.py
Output
Click Run to see the output here.

Output:

0
1
2
3
4

تفصيلتان عادةً ما تربكان المبتدئين:

  1. العد يبدأ من 0. فالاستدعاء range(5) يعطيك خمسة أرقام تبدأ من 0.
  2. قيمة التوقف غير مشمولة. أي أن range(5) يتوقف قبل الرقم 5، ولا يتضمن الرقم 5 نفسه.

هذه القاعدة ثابتة في بايثون سواء مع التقطيع (slicing) أو الفهرسة (indexing) أو مع دالة range. وبمجرد أن ترسّخ في ذهنك فكرة أن "قيمة التوقف غير مشمولة"، لن تقع في هذا الالتباس مرة أخرى.

الصيغ الثلاث لدالة range

تقبل دالة range() وسيطًا واحدًا أو اثنين أو ثلاثة:

main.py
Output
Click Run to see the output here.

الخطوة step هي حجم القفزة بين رقم وآخر. مثلاً range(0, 20, 4) يعطيك كل رقم رابع. خزّن هذه الفكرة جيداً، لأنها مفيدة جداً عندما تحتاج "كل عنصر ثاني" أو "كل عيّنة عاشرة".

العدّ التنازلي في بايثون

يمكن أن تكون الخطوة سالبة، وهذا ما يتيح لك العدّ التنازلي:

main.py
Output
Click Run to see the output here.

ولاحظ مرة أخرى أن قيمة التوقف (stop) غير مشمولة — فـ range(10, 0, -1) يتوقف قبل الصفر، لا عنده. وإذا أردت أن يشمل العد الصفر نفسه، اجعل قيمة التوقف -1:

main.py
Output
Click Run to see the output here.

دالة range في بايثون كسولة التنفيذ

في بايثون 3، دالة range() لا تُنشئ قائمة من الأرقام وتحتفظ بها في الذاكرة، بل تُرجع كائن range خفيف ينتج الأرقام واحداً تلو الآخر عند الحاجة فقط. ولهذا السبب يمكنك أن تكتب:

main.py
Output
Click Run to see the output here.

رقم واحد مليار داخل range لا يستهلك أي ذاكرة تقريبًا، لأن الأرقام تُولَّد لحظيًا بمجرد أن تطلبها الحلقة.

أما إذا كنت فعلًا بحاجة إلى قائمة بالأرقام — مثلًا لتعديلها أو ترتيبها أو الوصول إلى عناصرها بالفهرسة بشكل أوسع — فحوّلها صراحةً إلى list:

main.py
Output
Click Run to see the output here.

في الغالب، ما تحتاج تحوّلها إلى قائمة أصلاً. جملة for i in range(...) تشتغل مباشرةً.

أنماط شائعة مع range

هذه وصفات بسيطة راح تستخدمها باستمرار في حلقة for في بايثون:

تكرار شيء ما n مرة.

main.py
Output
Click Run to see the output here.

الرمز _ هو عُرف متعارف عليه بين المبرمجين، ومعناه باختصار: "القيمة دي مش مهمة بالنسبة لي". بايثون نفسها ما تُجبرك على استخدامه، لكن أي مبرمج يقرأ الكود راح يفهم المقصود على طول.

الوصول إلى عناصر تسلسل عبر الفهرس.

الأفضل دائمًا استخدام enumerate() بدل range(len(...))، لكن إذا كنت تحتاج الفهرس فقط لا غير:

main.py
Output
Click Run to see the output here.

Still, most of the time enumerate(items) is cleaner.

المرور على كل عنصر ثانٍ (تخطّي عنصر بين كل خطوة).

main.py
Output
Click Run to see the output here.

هذا سيطبع a و c و e. لكن إذا كنت تريد تقطيعًا بسيطًا، فإن صيغة الـ slicing أوضح وأقصر: items[::2].

توليد قائمة رقمية سريعة.

main.py
Output
Click Run to see the output here.

هذه تُسمى list comprehension — سنشرحها لاحقًا — لكن range هي التي توفّر الأرقام هنا.

ما لا تفعله دالة range()

هناك نقطتان حسّاستان يجب الانتباه إليهما:

  1. دالة range تُنتج أعدادًا صحيحة فقط. إذا احتجت خطوات عشرية (مثل الانتقال من 0.0 إلى 1.0 بخطوة 0.1)، فاستخدم numpy.arange أو اكتب حلقة بعدّاد خاص بك.
  2. range لا تعمل مع أي كائن قابل للتكرار. هي مخصّصة للأعداد الصحيحة تحديدًا. إذا كنت تحاول "المرور" على عناصر قائمة، فالأرجح أنك تبحث عن enumerate أو عن القائمة نفسها مباشرة.

نجمع كل شيء معًا

إليك مثالًا بسيطًا يستعرض عدة صيغ لدالة range دفعة واحدة:

main.py
Output
Click Run to see the output here.

حلقتان متداخلتان تعتمدان على range لتوليد شبكة. لاحظ أن كلتا الحلقتين تبدآن من 1 عبر range(1, 6)، لأننا نريد أرقاماً من 1 إلى 5.

الانتقال إلى المجموعات

حتى الآن تعرّفت على الشروط، وعلى نوعَي الحلقات، وعلى دالة range. هذا القدر من أدوات التحكم في التدفق يكفي للتعامل مع أي مجموعة بيانات. في الفصل القادم سننتقل إلى المجموعات نفسها: القوائم، والـ tuples، والـ sets، والقواميس.

الأسئلة الشائعة

ماذا تفعل دالة range() في بايثون؟

دالة range() تولّد متتالية من الأعداد الصحيحة. فمثلاً range(n) تعطيك الأرقام من 0 حتى n-1، بينما range(start, stop) تعطيك الأرقام ابتداءً من start وحتى stop دون أن تشمله. أما range(start, stop, step) فتسمح لك بتحديد مقدار الخطوة، وتقبل أيضاً خطوات سالبة للعد التنازلي.

هل تُنشئ دالة range() قائمة فعلية؟

لا. في بايثون 3 تُرجع range() كائن range خفيف الوزن يُولّد الأرقام عند الطلب فقط، ولهذا السبب فإن range(10**9) يُنفَّذ فوراً لأنه لا يحجز مليار عدد في الذاكرة. إذا احتجت قائمة حقيقية استخدم list(range(...)).

كيف أعدّ تنازلياً باستخدام range() في بايثون؟

استخدم خطوة سالبة، مثلاً range(10, 0, -1) ستنتج 10, 9, 8, ... , 1. وتذكّر أن قيمة stop لا تدخل ضمن النتيجة، فإذا أردت أن يظهر الرقم 0 في العد التنازلي فاكتبها هكذا: range(10, -1, -1).

تعلّم البرمجة مع Coddy

ابدأ الآن