حلقه while تک خطی در پایتون؛ چه زمانی استفاده کنیم؟

حلقه while تک خطی در پایتون؛ چه زمانی استفاده کنیم؟

آموزشی
26 مهر 1405

توجه: لازمه که بدونید این ویدیو تنها جزئی از دوره رایگان آموزش پایتون هستش.

 

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

 

حلقه while تک خطی در پایتون چیست؟

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

پس صحبت اصلی روی بدنه حلقه است، چون در حالت عادی کلمه while و شرط و در انتهای خط که دو نقطه (:) بود ثابت هستش در هر حالتی.

یک مثال از ساختار while تک خطی در پایتون:

ساختار حلقه تک خطی در پایتون

نکته: هر چیزی که بعد از دو نقطه تا اخر خط بیاد، جز بدنه حلقه است.

نمونه کد (این دو خط دقیقا یکسان هستند):

# تک‌خطی
while floor < 5: floor += 1

# چندخطی
while floor < 5:
    floor += 1

برای پایتون هر دو حالت یکسان اند و سرعت اجرای اون ها هم یکسان است پس وقتی به این سوال بر میخورید که تک خطی بنویسم یا نه فقط و فقط یک چیز باید از خودتون بپرسید: " کدوم خواناتره "

 

چند دستور (statement) در while تک خطی با نقطه ویرگول یا semi colon (;)

با ; میشود چند دستور یا statement رو در پایتون در یک خط نوشت. پس دقت داشته باشید که همه دستور های بعد از دو نقطه حلقه while جز بدنه حلقه هستند (نه فقط اولی).

مثال:

floor = 0
while floor < 3: floor += 1; print("Floor", floor)
print("Arrived")

خروجی:

Floor 1
Floor 2
Floor 3
Arrived

دقت کردید که print ای که بعد از ; نوشتید در هر دور حلقه اجرا شد.

توجه: صرفا چون میشود چندین دستور رو با ; در پایتون به صورت خطی نوشت، دلیل بر این نیست که هر جایی انجامش بدید، زمانی که کمکی به خوانایی نمیکنه پس انجامش کاملا اشتباه است.

 

ترکیب while تک خطی با if else تک خطی در پایتون

اعتقاد شدیدی به یادگیری با مثال دارم پس بیاید این بخش رو با یک مثال پله پله پیش ببریم:

فک کنید یک اسانسور باید به طبقه target برورد، یعنی :

  • اگر طبقه (floor) پایین تر از مقصد (target) بود: باید اسانسور بالا برود
  • اگر طبقه (floor) بالاتر از مقصد (target) بود: باید اسانسور پایین برود

نسخه کد چند خطی همین مثال:

while floor != target:
    if floor < target:
        floor += 1
    else:
        floor -= 1

خب اگر بخوایم با اولین چیزی که به ذهنمون میرسه تک خطی کنیم این کد رو مینوسیم.

سینتکس اشتباه:

while floor != target: if floor < target: floor += 1

خطا:

SyntaxError: invalid syntax

چرا خطا گرفیتم؟

چون بعد از دو نقطه while نمیشه یک if کامل تک خطی با دو نقطه (:) خودش شروع کرد.

وقتی که دارید statement ها یا دستورات رو به صورت خطی مینویسید و با ; از هم جدا میکنید باید توجه کنید پایتون در هر بخش فقط یک دستور ساده میگیره نه دستورات چند بخشی.

یعنی اون سینتکس تک خطی با : در if تکی خطی رو نمیتونید به عنوان یک statement یا دستور در بدنه while تک خطی بنویسید.

اما شرط های تک خطی در پایتون به شکل دیگه هم نوشته میشه که میتونید از اون سینتکس برای ترکیبش با while استفاده کنید.

 

راه حل: if/else تک خطی که مقدار انتخاب میکنه

پایتون یک شکل کوتاه از if/else داره که به جای انجام دادن کار بین دو مقدار یکی رو انتخاب میکنه (همون ساختار عادی if else پایتون):

ساختار شرط تک خطی در پایتون

به زبان ساده عکس میگه: اگه طبقه فعلی پایین تر از مقصد هستش 1 برگردان وگرنه -1 .

پس در نتیجه شرط تک خطی بالا فقط یک جواب بیرون میده: یا 1 است یا -1 پس میشه اون رو مستقیم به floor اضافه کنیم و کل حلقه رو در یک خط بنویسیم:

while floor != target: floor += 1 if floor < target else -1

اگر آسانسور پایین تر از مقصد بود، یک طبقه بالا میره (منظور در هر دور از حلقه است)؛ و اگر بالاتر بود پس یک طبقه پایین می اید؛ دقیقا همون کار نسخه چند خطی ولی در یک خط.

قانون ساده برای گیک ها:

داخل while تک خطی، عملا if نمیتونه کاری انجام بده، بلکه فقط میتونه یک مقداری رو انتخاب کنه.

برای همین باید شرط if else میشد در حلقه while تک خطی ولی if تنها رو نمیشد به صورت تک خطی با while ترکیب کرد.

 

چند مثال کاربردی از while تک خطی

 

1- شارژ باتری: سریع تا 80 درصد، بعد آهسته

battery = 20
while battery < 100: battery += 30 if battery < 80 else 10
print(battery)

خروجی:

100

مثلا فست شارژ خیلی از گوشی ها که تا وقتی باتری زیر 80 درصد هستش، سرعت شارژ سریعه ولی بعد از اون کند تر میشه.

 

2- فرم ورود با شمارش تلاش ها

tries = 1
while input("Password: ") != "1234": tries += 1
print("Welcome!" if tries == 1 else f"Welcome after {tries} tries")

خروجی:

Password: 0000
Password: 1111
Password: 1234
Welcome after 3 tries

توضیح مثال:

تا وقتی رمز اشتباه است دوباره میپرسه و تعداد تلاش ها رو میشماره و بعد از حلقه با یک if/else تک خطی پیام مناسب رو انتخاب میکنه.

 

ادامه شرط while در خط بعد با بک اسلش (\)

اگر زمانی شرط شما اونقدری طولانی شد که دیگه توی یک خط جا نمیشد میتونید \ بزارید و ادامه اش رو توی خط بعد بنویسید و ارور هم دریافت نمیکنید.

while tries < MAX_TRIES and password != "1234" \
        and not account_locked:
    password = input("Password: ")
    tries += 1

در واقع این \ داره به پایتون میگه این خط تموم نشده پس در اصل پایتون این دو خط رو یک خط حساب میکنه.

برای همین تو رفتگی دوم اصلا برای پایتون مهم نیست و در واقع چیزی که پایتون میخونه، چیزی شبیه به اینه:

while tries < 3 and         password != "1234":

نکته مهم برای گیک ها:

\ باید آخرین کارکتر باشه حتی فاصله نامرئی یا یک کامنت هم بعد از اون باشه همجین خطایی میگیرید:

SyntaxError: unexpected character after line continuation character

 

کی while را تک خطی بنویسیم و کی نه؟

تک خطی مناسب استچند خطی مناسب است
بدنه منطق ساده ای داردبدنه پیچیده است و چندین کار را انجام میدهد
یک انتخای ساده بین مقدار با if/else تک خطیدستور if، break یا عبارت های شرطی تو در تو لازم است
خط طولانی نمیشود (مثلا زیر 79 کارکتر)کد زیاد است و حتی کامنت هم لازم دارد
اسکریپت کوتاه شخصیپروژه تیمی با Black یا ruff format (خودشان اون رو چند خطی میکنند)

راهنمای رسمی خود پایتون PEP8هم داره همین رو میگه : تک خطی برای بدنه کوچک گاهی اشکال ندارد ولی پیشفرض نیست.

اگه به یادگیری اصول PEP 8 علاقه دارید مقاله PEP 8 چیست رو مطالعه کنید. 

 

جمع بندی

اگر بخوام فقط با یک جمله جمع بندی کنم میگم که:

" اگر برای فهمیدنش باید دوبار بخونی پس تک خطیش نکن "

author-avatar
سعید امینینویسنده مقاله

الان بیشتر از 6 ساله که مشغول برنامه نویسی وب هستم و در طول این مدت کلی چالش رو پشت سر گذاشتم و عاشق اینم که هر چیزی رو که در این مدت یاد گرفتم رو به بقیه هم یاد بدم، الانم در بستر سایت گیک باز دارم دانشم رو با بقیه تقسیم میکنم :)

نظرات

هنوز نظری وجود ندارد! شما اولین نفر باشید...