استفاده از or و and به جای شرط در python

یکی از ترفند های کدزنی که برنامه‌نویسان حرفه‌ای معمولا از آن استفاده می‌کنند استفاده از or و and به جای شرط است. بله درست متوجه شدید، به جای شرط. این ترفند ممکن است باعث شود تا کد شما خوانا نباشد و حتی توصیه شده نیست ولی ترفند به شدت جذابی‌ست که می‌تواند در خلاصه نویسی کد تاثیر زیادی داشته باشد. این روش در بسیاری زبان ها مانند C, JavaScript, Python و … کاربرد دارد. پس با ما همراه باشید تا این تکنیک زیبا و جذاب را یاد بگیرید.

حتما تا کنون از and و or استفاده کردید، شرایط زیر را در نظر بگیرید:

if a > 0 and a%2==1:
    print('a is odd number')

کد بالا یک نمونه ساده از کاربرد ترکیب عطف منطقی یا همون «و» در پایتون است. همانطور که می‌دانید کاربرد عمومی این ترکیب های منطقی (and, or) بیشتر در شرط‌ها هستند. بیایید ببینیم این عملگر ها چطور کار می‌کنند.

OR

ترکیب منطقی «یا» در سه حالت جواب «درستی» یا همان True دارد. و تنها زمانی که هر دو گزاره راست و چپ آن غلط باشند جواب غلط یا false خواهد داشت.

True or True = True
True or False = True
False or True = True
False or False = False

AND

ترکیب منطقی «و» فقط در یک حالت جواب «درستی» دارد و آن زمانیست که هر دو سمت آن درست باشند:

True and True = True
True and False = False
False and True = False
False and False = False

مطالبی که تا اینجا گفته شد جزء مطالب ابتدایی هستند و افرادی که برنامه‌نویسی می‌کنند از آن ها آگاهند. اما نکته اینجاست که در پایتون این عملگر ها به چه صورت عمل می‌کنند. ابتدا عملگر or را بررسی می‌کنیم:

تعریف عملگر OR

def or (left, right):
    if left:
        return left
    return right

بسیاری از زبان های برنامه نویسی عموما عملگر or را به این شکل تعریف می‌کنند. فراموش نکنید برای جواب درستی در این عملگر صحیح بودن یکی از طرفین کافیست بنابراین اگر شرط اول یعنی left صحیح بود دیگر نیازی به بررسی سمت راست عبارت نیست و عملگر or همان left را بر می‌گرداند. این کار سبب افزایش سرعت و کاهش هزینه زمانی می‌شود.

برای ترکیب and تعریف این عملگر به این صورت است:

تعریف عملگر AND

def and (left, right):
    if not left:
        return left
    return right

در این تعریف عملگر and ابتدا سمت چپ عبارت را بررسی می‌کند، اگر سمت چپ عبارت مقدار غلط داشته باشد همین کافیست تا مقدار غلطی سمت چپ برگردانده شود و جواب کل عبارت غلط یا False شود؛ اما در غیر اینصورت باید دید ارزش گزاره سمت راست چگونه است. اگر آن نیز درست بود پس ارزش کل درست و درغیر این صورت غلط است.

جالب است بدانید این عملگر ها در زبان لیسپ تنها به صورت ماکرو هستند و زمان کامپایل شدن به همان شیوه شرطی تبدیل می‌شوند

شرط ایمن

عنوان بهتری برای این بند به ذهنم نرسید ولی نکته جالبی هست که لازم هست در اینجا ذکرش کنم. همون طور که در عبارت بالا دیدید عملگر های or و and از چپ به راست عبارت را بررسی می‌کنند. این کار می‌تواند در بسیاری مواقع به ما کمک کنند. مثلا فرض کنید متغیر a می‌تواند None یا str (و یا هر مقدار دیگری) باشد و در عین حال شما می‌خواهید عدد بودن آن را بررسی کنید. کد های زیر را در نظر بگیرید. یکی از این کد ها بدون خطا و کد دیگر خطا می‌دهد:

کد بدون خطا:

if isinstance(a,str) and a.isdigit():
    return int(a)

کد غلط:

if a.isdigit() and isinstance(a,str):
    return int(a)

در کد اول ابتدا str بودن a بررسی می‌شود؛ اگر a یک رشته نبود عبارت سمت راست بررسی نمی‌شود اما اگر رشته بود تابع isdigit آن که از توابع str است فراخوانی می‌شود. در مثال دوم این روند برعکس است در نتیجه اگر a تهی باشد خطای AttributeError می‌دهد.

سوء استفاده از این عملگر ها!

حالا که می‌دانیم قضیه از چه قرار است و درواقع این عملگر ها خود به نوعی شرط هستند، می‌خواهیم از آن ها (سوء) استفاده کنیم! همان‌طور که در تعاریف دیدید این عملگر ها خود مقدار را بر می‌گردانند، برای مثال کد زیر را در نظر بگیرید:

>>> 0 or 10
10
>>> 0 and 10
0

همانطور که می‌دانید در پایتون عدد ۰ همانند مقدار تهی (None) و رشته خالی و … ارزش غلط (False) دارد. به همین خاطر نتیجه کد بالا به این‌صورت است و زمانی که آن را در یک شرط استفاده می‌کنیم ۰ یا None را به عنوان False می‌شناسد و ادامه ماجرا …

اما از این خاصیت می‌توانیم به شکل دیگری استفاده کنیم:

a = input('give me some input: ') or 'something'

این تکه کد از خاصیت or استفاده می‌کند تا متغیر a هرگز یک رشته خالی نباشد. به نحوی که اگر کاربر رشته خالی وارد کند عملگر or سمت راست عبارت را بر می‌گرداند در نتیجه a برابر می‌شود با 'something'. این کد را می‌توان به روش های زیر هم نوشت:

inp = input('give me some input: ')
if inp:
    a = inp
else:
    a = 'something'
inp = input('give me somt input: ')
a = inp if inp else 'something'

در مثال های بالا از or برای مقدار دهی استفاده کردیم. حال مثال زیر را ببینید:

a%5 or print('a is divisible by five')

در این مثال در سمت چپ عبارت a%5 را داریم. اگر حاصل این عبارت برابر با بیشتر از صفر شود ارزش درستی خواهد داشت و or همان مقدار را بر می‌گرداند اما اگر مقدار آن صفر شود ارزش نادرستی خواهد داشت و or به سراغ عبارت سمت چپ می‌رود و در نتیجه جمله «a بر ۵ بخش‌پذیر است» به کاربر نمایش داده می‌شود زیرا باقیمانده تقسیم صفر شده. این کد را می‌توان به این شکل نوشت:

if a%5==0:
    print('a is divisible by five')

برای عکس این مسئله می‌توانید از کد زیر استفاده کنید:

a%5 and print('a is not divisible by five')

همانطور که در تعریف عملگر and گفته شده تفاوت آن با or این است که بخش اول آن not یا نقیض شده. بنابراین در این تکه کد زمانی که حاصل عبارت a%5 از صفر بزرگ‌تر است جمله «a بر ۵ بخش‌پذیر نیست» نمایش داده می‌شود اما در غیر این‌صورت مقدار ۰ برگردانده خواهد شد.

توجه کنید که در این دو مثال مقدار برگردانده شده به کاربر نشان داده نمی‌شود، بنابراین به سادگی می‌توانید از این کد ها استفاده کنید.

کدنویسی استاندارد

این روش ها بسیار جالب و برگرفته از درک چگونگی عملگرد این عملگر ها است اما پیچیده هستند و خوانا نیستند. یعنی برای آن که برنامه‌نویس دیگری آن را درک کند باید منطق آن توضیح داده شود. لذا استفاده از این ها در جهت خوانا تر شدن کد زیاد توصیه نمی‌شوند؛ از طرفی ممکن است خود نویسنده را دچار مشکل کند. بنابراین یا از این کد ها استفاده نکنید و آن ها را خوانا تر کنید و یا اگر استفاده می‌کنید در کامنتِ کدتان، آن را شرح دهید و خود و دیگران راحت کنید!

5 دیدگاه برای “استفاده از or و and به جای شرط در python”

    1. به نظرم استفاده از این کد مشکلی که داره اینه که خوانا نیست. یعنی اگه برای if مثلا ۲ ثانیه طول بکشه تا درکش کنی برای این حدود ۱۰ ثانیه باید وقت بذاری تا بفهمیش. از طرفی این باعث میشه ریسک کد بالا بره و اشتباه هم پیش بیاد

      1. در مورد زمان فهمیدن، وقتی همه استفاده کنن عادت میکنیم و مشکلی پیش نمیاد. البته جاوا اسکریپت با پایتون فرق داره و گفتم که من اینکار رو بیشتر توی کد های جاوا اسکریپت دیدم تا پایتون.
        و البته یک فرق دیگه جاوا اسکریپت و پایتون اینه که توی جاوا اسکریپت هر چی وجود نداشته باشه undefined هست یعنی مقدار تعریف نشده و مثلا some_rAnDom_var هم خودش مقدار داره.