کنترل جریان
شرط در پایتون: if، elif، else و شرطهای تودرتو
تا اینجا برنامهها خط به خط از بالا به پایین اجرا میشدند. اما برنامهٔ واقعی باید تصمیم بگیرد: اگر رمز درست بود وارد شو، وگرنه خطا بده. سادهترین دستور انشعاب (branching) دستور شرطی است که سه بخش دارد:
- یک تست: عبارتی که نتیجهاش
TrueیاFalseاست. - یک بلوک کد که اگر تست درست بود اجرا شود.
- یک بلوک اختیاری که اگر تست نادرست بود اجرا شود.
┌──────┐
│ کد │
└──┬───┘
▼
◇ تست ◇
True False
▼ ▼
بلوک True بلوک False
└───┬────┘
▼
┌──────┐
│ ادامه │
└──────┘
if و else
x = int(input("Enter an integer: "))
if x % 2 == 0:
print("")
print("Even")
else:
print("")
print("Odd")
print("Done with conditional")
دقت کنید:
- بعد از شرط و بعد از
elseدونقطه (:) میآید. - خطوط داخل هر بلوک تورفتگی (indentation) دارند. در پایتون تورفتگی بخشی از دستور زبان است، نه فقط زیبایی. پایتون از روی تورفتگی میفهمد کدام خطوط مال کدام بلوکاند.
- خط آخر تورفتگی ندارد، پس بیرون از
if/elseاست و در هر صورت اجرا میشود.
💡 استاندارد پایتون برای هر سطح تورفتگی ۴ فاصله است. ویرایشگرها با زدن Tab خودشان ۴ فاصله میگذارند. هیچوقت تب و فاصله را در یک فایل قاطی نکنید.
else اختیاری است. اگر نباشد و شرط نادرست باشد، پایتون بیسروصدا از روی بلوک رد میشود.
elif: چند حالت
وقتی بیش از دو حالت داریم، از elif (مخفف else if) استفاده میکنیم:
a = 200
b = 33
if b > a:
print("b is greater than a")
elif a == b:
print("a and b are equal")
else:
print("a is greater than b")
پایتون شرطها را به ترتیب بررسی میکند و فقط اولین شرطی که درست باشد اجرا میشود؛ بقیه دیگر بررسی نمیشوند. else آخر هم شرطی ندارد: «اگر هیچکدام نبود».
if <condition>:
<expressions>
elif <condition>:
<expressions>
else:
<expressions>
شرط تودرتو
داخل یک بلوک if میشود یک if دیگر نوشت (با یک سطح تورفتگی بیشتر):
x = 12
if x % 2 == 0:
if x % 3 == 0:
print("Divisible by 2 and 3")
else:
print("Divisible by 2 and not by 3")
elif x % 3 == 0:
print("Divisible by 3 and not by 2")
چرا برای حالت فرد، else و داخلش یک if دیگر ننوشتیم؟ چون اگر به elif برسیم، مطمئنیم عدد فرد است (وگرنه وارد if اول شده بود). پس فقط کافی است بخشپذیری بر ۳ را بررسی کنیم. خط کمتر، منطق یکسان.
ترکیب شرطها با and و or
x, y, z = 8, 3, 5
if x < y and x < z:
print("x is least")
elif y < z:
print("y is least")
else:
print("z is least")
باز هم دقت کنید: وقتی به elif میرسیم، میدانیم x کوچکترین نیست. پس فقط کافی است y و z را مقایسه کنیم.
مسئله: مرتب کردن سه عدد
برنامهای بنویسید که سه عدد بگیرد و آنها را از کوچک به بزرگ چاپ کند.
این مسئلهٔ ساده نشان میدهد که برای یک مسئله چند راهحل با کیفیتهای خیلی متفاوت وجود دارد.
راهحل ۱: همهٔ حالتها با elif
سه عدد ۶ ترتیب ممکن دارند؛ میشود همه را نوشت:
a = int(input("عدد وارد کن: "))
b = int(input("عدد وارد کن: "))
c = int(input("عدد وارد کن: "))
if a < b < c:
print(a, b, c)
elif a < c < b:
print(a, c, b)
elif b < a < c:
print(b, a, c)
elif b < c < a:
print(b, c, a)
elif c < a < b:
print(c, a, b)
elif c < b < a:
print(c, b, a)
else:
print("حداقل دو تا مساویاند")
کار میکند، ولی طولانی است و حالتهای مساوی را هم درست مرتب نمیکند.
راهحل ۲: شرط تودرتو
با هر مقایسه، نیمی از حالتها حذف میشوند:
a = int(input("a: "))
b = int(input("b: "))
c = int(input("c: "))
if a < b:
if b < c:
print(a, b, c)
elif a < c:
print(a, c, b)
else:
print(c, a, b)
else:
if a < c:
print(b, a, c)
elif b < c:
print(b, c, a)
else:
print(c, b, a)
در بدترین حالت فقط سه مقایسه انجام میشود و اعداد مساوی هم درست مرتب میشوند.
راهحل ۳: جابهجا کردن متغیرها
ایدهٔ هوشمندانهتر: بهجای چاپ مستقیم، مقدار متغیرها را آنقدر جابهجا کنیم تا همیشه a ≤ b ≤ c شود:
a = int(input("a: "))
b = int(input("b: "))
c = int(input("c: "))
if a > b:
a, b = b, a # حالا a کوچکترِ a و b است
if a > c:
a, c = c, a # حالا a کوچکترین هر سه است
if b > c:
b, c = c, b # و b از c کوچکتر
print(a, b, c)
بدون هیچ شرط تودرتویی، کوتاه و خوانا. این در واقع یک نسخهٔ کوچک از الگوریتمهای مرتبسازی است.
💡 در عمل، پایتون برای مرتبسازی تابع آماده دارد:
print(sorted([a, b, c])). ولی فکر کردن به این راهحلها همان چیزی است که شما را برنامهنویس میکند.
تمرین
۱. کوچکترین عدد
سه عدد بگیرید و فقط کوچکترین را چاپ کنید (بدون sorted و min).
جواب
a = int(input("a: "))
b = int(input("b: "))
c = int(input("c: "))
if a < b and a < c:
print("a کوچکترین است:", a)
elif b < c:
print("b کوچکترین است:", b)
else:
print("c کوچکترین است:", c)
۲. سال کبیسه (میلادی)
سالی کبیسه است که بر ۴ بخشپذیر باشد، مگر اینکه بر ۱۰۰ بخشپذیر باشد؛ ولی اگر بر ۴۰۰ بخشپذیر باشد، باز هم کبیسه است. برنامهای بنویسید که یک سال بگیرد و بگوید کبیسه است یا نه. با ۲۰۲۴ (کبیسه)، ۱۹۰۰ (نه) و ۲۰۰۰ (کبیسه) تست کنید.
جواب
year = int(input("سال: "))
if year % 400 == 0:
print("کبیسه")
elif year % 100 == 0:
print("کبیسه نیست")
elif year % 4 == 0:
print("کبیسه")
else:
print("کبیسه نیست")
یا در یک خط: (year % 4 == 0 and year % 100 != 0) or year % 400 == 0