کنترل جریان
حلقهٔ for و range در پایتون؛ break و continue
خیلی وقتها با حلقه میخواهیم بشماریم: ۰ تا ۹، ۱۰ تا ۱۰۰ دهتادهتا، یا روی تکتک حروف یک کلمه. با while باید سه جای مختلف را مدیریت کنیم (مقدار اولیه، شرط، افزایش). for همهٔ اینها را در یک خط خلاصه میکند:
# با while
n = 0
while n < 5:
print(n)
n = n + 1
# همان کار با for
for n in range(5):
print(n)
ساختار for
for <متغیر> in <دنباله>:
<دستورها>
- در هر دور،
<متغیر>یک مقدار از دنباله میگیرد؛ - بار اول اولین مقدار، دفعهٔ بعد مقدار بعدی، و همینطور تا آخر؛
- بدنهٔ حلقه هر بار با مقدار جدید اجرا میشود.
دیگر لازم نیست خودتان متغیر را زیاد کنید، پس حلقهٔ بینهایت تصادفی هم نخواهید داشت.
تابع range
range(شروع, توقف, گام)
- مقدار پیشفرض شروع ۰ و گام ۱ است و میشود ننوشتشان.
- شمارش تا یکی قبل از توقف ادامه پیدا میکند. خود توقف جزو نتیجه نیست؛ همان قانون برش رشتهها.
print(list(range(5))) # [0, 1, 2, 3, 4]
print(list(range(3, 10))) # [3, 4, 5, 6, 7, 8, 9]
print(list(range(3, 10, 2))) # [3, 5, 7, 9]
print(list(range(10, 101, 10)))
print(list(range(10, 1, -2))) # گام منفی: شمارش معکوس
(اینجا list فقط برای این است که همهٔ مقدارها را یکجا ببینیم.)
💡
range(5)واقعاً یک فهرست ۵ عددی در حافظه نمیسازد؛ هر عدد را همان لحظهای که لازم است تولید میکند. برای همینrange(1_000_000_000)هم تقریباً هیچ حافظهای نمیگیرد. به این ویژگی «تنبل» (lazy) بودن میگویند. بعدها با generatorها بیشتر آشنا میشویم.
mysum = 0
for i in range(7, 10):
mysum += i
print(mysum) # 7 + 8 + 9 = 24
mysum = 0
for i in range(5, 11, 2):
mysum += i
print(mysum) # 5 + 7 + 9 = 21
حلقه روی رشته
for فقط روی اعداد کار نمیکند؛ روی هر دنبالهای میچرخد. مثلاً روی کاراکترهای یک رشته:
for ch in "salam":
print(ch)
این بسیار پرکاربرد است و در درس متدهای رشته مفصلتر میبینیمش.
break: خروج فوری از حلقه
break بلافاصله از حلقه بیرون میآید و بقیهٔ دستورهای آن دور را هم اجرا نمیکند.
mysum = 0
for i in range(5, 11, 2):
mysum += i
if mysum == 5:
break
print(mysum)
قبل از اجرا حدس بزنید خروجی چیست! (جواب: 5. در اولین دور mysum میشود ۵ و حلقه همانجا تمام میشود.)
اگر حلقهها تودرتو باشند، break فقط از درونیترین حلقه بیرون میآید:
while condition_1:
while condition_2:
expression_a
break # فقط از حلقهٔ درونی خارج میشود
expression_b # هیچوقت اجرا نمیشود
expression_c # بعد از break اینجا ادامه پیدا میکند
continue: پریدن به دور بعد
continue بقیهٔ همین دور را رها میکند و سراغ دور بعدی میرود (از حلقه خارج نمیشود):
for i in range(1, 11):
if i % 3 == 0:
continue # مضربهای ۳ را رد کن
print(i, end=" ")
for یا while؟
for |
while |
|
|---|---|---|
| کاربرد | وقتی تعداد دورها یا دنباله معلوم است | وقتی فقط شرط توقف را میدانید |
| مثال | ۱ تا ۱۰۰، هر حرف یک کلمه | تا وقتی کاربر q نزده |
| حلقهٔ بینهایت تصادفی | تقریباً غیرممکن | اگر متغیر را زیاد نکنید، بله |
هر for را میشود با while نوشت (برعکسش همیشه ممکن نیست)، ولی وقتی چیزی را میشمارید، for کوتاهتر و امنتر است.
تمرین
۱. اعداد زوج
با for کدی بنویسید که خروجیاش این باشد:
2
4
6
8
10
Goodbye!
جواب
for i in range(2, 11, 2):
print(i)
print("Goodbye!")
۲. شمارش معکوس
حالا این را:
Hello!
10
8
6
4
2
جواب
print("Hello!")
for i in range(10, 1, -2):
print(i)
۳. هوپ!
اعداد ۰ تا ۵۰ را در یک خط و با * بینشان چاپ کنید، ولی بهجای مضربهای ۵ کلمهٔ hop را بنویسید.
جواب
for i in range(51):
if i % 5 == 0:
print("hop", end="*")
else:
print(i, end="*")
یک نکتهٔ جالب: if not i % 5: هم همین کار را میکند. وقتی i % 5 صفر باشد، ارزش منطقیاش False است و not آن را True میکند. ولی نسخهٔ == 0 خواناتر است.
۴. جمع ۱ تا end
یک حلقهٔ for بنویسید که جمع اعداد ۱ تا end (با خود end) را حساب کند. مثلاً برای end = 6 جواب 21 است.
جواب
end = 6
total = 0
for i in range(1, end + 1):
total += i
print(total)
دقت کنید: range(1, end) خود end را شامل نمیشود، برای همین end + 1 نوشتیم. این اشتباه «یکی کم/زیاد» (off-by-one) از رایجترین باگهای دنیاست!