کنترل جریان

حلقهٔ while در پایتون: تکرار تا وقتی شرط برقرار است

۴ دقیقه مطالعه · به‌روزرسانی ۲۲ مهر ۱۴۰۵

دستور شرطی به برنامه اجازه می‌دهد مسیر اجرا را انتخاب کند. حلقه به برنامه اجازه می‌دهد یک بلوک کد را بارها تکرار کند، حتی وقتی از قبل نمی‌دانیم چند بار. با شرط و حلقه می‌شود برنامه‌هایی با پیچیدگی دلخواه نوشت.

        ┌──────┐
        │  کد  │
        └──┬───┘
           ▼
   ┌──▶ ◇ تست ◇ ── False ──┐
   │       │ True           │
   │       ▼                │
   │  ┌──────────┐          │
   └──┤ بدنهٔ حلقه│          │
      └──────────┘          ▼
                        ┌──────┐
                        │ ادامه │
                        └──────┘

۱. تست بررسی می‌شود. ۲. اگر True بود، بدنهٔ حلقه یک بار اجرا می‌شود و دوباره سراغ تست برمی‌گردیم. ۳. وقتی تست False شد، اجرا از خط بعد از حلقه ادامه پیدا می‌کند.

اولین while

n = 0
while n < 5:
    print(n)
    n = n + 1
print("تمام")

مثل if، بعد از شرط : می‌آید و بدنهٔ حلقه تورفتگی دارد.

سه ویژگی متغیر حلقه

تقریباً هر حلقهٔ while یک متغیر حلقه دارد که سه شرط را باید داشته باشد:

  1. بیرون از حلقه مقدار اولیه بگیرد: n = 0
  2. داخل حلقه تغییر کند: n = n + 1
  3. شرط پایان بر اساس همین متغیر بررسی شود: while n < 5

اگر شرط ۲ را فراموش کنید، شرط هیچ‌وقت False نمی‌شود و حلقهٔ بی‌نهایت دارید. برنامه هیچ‌وقت تمام نمی‌شود. (در Jupyter با دکمهٔ ■ یا I I متوقفش کنید؛ در ترمینال با Ctrl+C. این سایت هم اجرای بیش از ۱۵ ثانیه را خودش قطع می‌کند.)

ردگیری اجرا: ضرب با جمع

این برنامه x * x را فقط با جمع حساب می‌کند:

x = 3
ans = 0
iters_left = x
while iters_left != 0:
    ans = ans + x
    iters_left = iters_left - 1
print(str(x) + "*" + str(x) + " = " + str(ans))

بیایید مثل کامپیوتر، خط به خط اجرایش کنیم و مقدار متغیرها را در یک جدول نگه داریم:

قدم تست iters_left != 0 ans iters_left
شروع 0 3
دور ۱ 3 != 0 → True 0 + 3 = 3 2
دور ۲ 2 != 0 → True 3 + 3 = 6 1
دور ۳ 1 != 0 → True 6 + 3 = 9 0
پایان 0 != 0 → False 9 0

بعد از اینکه تست False شد، print اجرا می‌شود: 3*3 = 9.

💡 این مهارت را جدی بگیرید. ردگیری دستی کد با جدول متغیرها (به آن «trace» یا «dry run» می‌گویند) بهترین راه پیدا کردن باگ و فهمیدن کد دیگران است. وقتی کدی کار نمی‌کند، به‌جای حدس زدن، یک جدول بکشید.

الگوی «جمع‌زدن» (Accumulator)

یکی از رایج‌ترین الگوهای برنامه‌نویسی: یک متغیر را از صفر شروع کنید و در هر دور حلقه چیزی به آن اضافه کنید.

# جمع اعداد ۱۰ تا ۲۰
my_sum = 0
i = 10
while i <= 20:
    my_sum += i
    i += 1
print(my_sum)

برای اینکه ببینید داخل حلقه چه می‌گذرد، یک print موقت داخلش بگذارید:

my_sum = 0
i = 10
while i <= 20:
    my_sum += i
    print(f"i = {i}, my_sum ta inja: {my_sum}")
    i += 1
print(my_sum)

💡 این «print برای دیباگ» ساده‌ترین ابزار عیب‌یابی است. وقتی مطمئن شدید کد درست کار می‌کند، پاکش کنید.

با تغییر گام (مثلاً i += 2) می‌شود فقط اعداد زوج را جمع زد:

my_sum = 0
i = 10
while i <= 20:
    my_sum += i
    i += 2
print(my_sum)   # 10+12+14+16+18+20 = 90

while کِی به کار می‌آید؟

اگر می‌خواهید بشمارید (۱ تا ۱۰، هر ۵ تا یک بار، …)، حلقهٔ for معمولاً ساده‌تر و امن‌تر است. while برای وقتی است که نمی‌دانید چند بار باید تکرار کنید و فقط شرط توقف را می‌دانید:

  • تا وقتی کاربر q را نزده، ادامه بده؛
  • تا وقتی سنسور دمای مشخصی را گزارش نکرده، صبر کن؛
  • تا وقتی خطاهای فایل تمام نشده، بخوان؛
  • تا وقتی جواب به اندازهٔ کافی دقیق نشده، حدس بزن (در بخش تفکر الگوریتمی می‌بینیم).
password = ""
while password != "1234":
    password = input("رمز را وارد کنید (1234): ")
print("خوش آمدید!")

تمرین

۱. میانگین ۱ تا n

برنامه‌ای بنویسید که n را از کاربر بگیرد و میانگین اعداد ۱ تا n را با while حساب کند.

جواب
n = int(input("n: "))
total = 0
i = 1
while i <= n:
    total += i
    i += 1
print("میانگین:", total / n)

(ریاضی‌دان‌ها می‌دانند جواب همیشه (n + 1) / 2 است. با این فرمول جوابتان را چک کنید!)

۲. پیدا کردن باگ

این برنامه قرار است اعداد ۱ تا ۱۰ را چاپ کند ولی به‌جای ۵ کلمهٔ «پنج» را. چرا هیچ‌وقت تمام نمی‌شود؟

i = 1
while i <= 10:
    if i == 5:
        print("پنج")
    else:
        print(i)
        i += 1
جواب

i += 1 داخل else است. وقتی i به ۵ می‌رسد، وارد if می‌شود و i دیگر هیچ‌وقت زیاد نمی‌شود: حلقهٔ بی‌نهایت که مدام «پنج» چاپ می‌کند. تورفتگی i += 1 را یک سطح کم کنید تا بیرون از if/else و داخل حلقه باشد:

i = 1
while i <= 10:
    if i == 5:
        print("پنج")
    else:
        print(i)
    i += 1