پایتون یک زبان برنامهنویسی شئگرا است و از آنجایی که نزدیکی بسیار زیادی با زبان انگلیسی دارد، یادگیری و استفاده از آن بسیار ساده است. به همین دلیل است که پایتون را اغلب برای یادگیری افراد مبتدی پیشنهاد میکنند. ویژگیهای حرفهای و همچنین کتابخانههای بسیار زیادی که در پایتون وجود دارد باعث شده که حتی سختترین مشکلات و مسائل دنیای برنامهنویسی در اینجا صرفا با نوشتن چند خط کد به سادگی انجام شود. در این مطلب قصد داریم به بررسی ویژگیهای حرفهای پایتون بپردازیم که انجام کارهای مختلفی را برای ما ساده کرده است.
List comprehension
List comprehension یک روش سریع و کوتاه در پایتون است که ما با استفاده از آن میتوانیم براساس یک شرط، یک حلقه for را روی یک شئ با قابلیت تکرارپذیری (مثل آرایه) اعمال بکنیم. اینگونه میتوانیم بسیار سریعتر روی یک آرایه خروجی فیلترداری را دریافت کنیم.
سینتکس کلی:
[some_operation(element) for element in sequence]
- returns list of elements.
مثال:
def segregate(arr):
return [x for x in arr if x%2 == 0] + [x for x in arr if x%2 != 0]
if __name__ == '__main__':
arr = [1, 8, 5, 3, 2, 6, 7, 10]
arr = segregate(arr)
print (arr)
# prints [8, 2, 6, 10, 1, 5, 3, 7]
در بالا میتوانیم یک تابع با نام segregate را مشاهده کنیم که یک آرایه را به عنوان ورودی میگیرد و در نهایت یک لیست از پیوند اعداد زوج و فرد آرایه را به صورت مرتب به ما برمیگرداند. برنامه تا زمانی که For اول تمام زوجها را بدست نیاورد سراغ For بعدی نمیرود.
Slicing
Slicing زمانی استفاده میشود که ما قصد داشته باشیم تا یک زنجیره یا زیر زنجیره از یک المان را شخصیسازی بکنیم. برای مثال در یک آرایه اندیسهای قبل از عضو b یا بعد از آن را بدست بیاوریم.
سینتکس کلی:
list[start_index : end_index : step_size]
- returns list of elements.
- default start_index is 0.
- default end_index is -1.
- default step_size is 1.
مثال:
def rotate(arr, d):
return arr[d:] + arr[:d]
if __name__ == '__main__':
arr = [1, 2, 3, 4, 5, 6, 7, 8]
arr = rotate(arr, 3)
print (arr)
# prints [3 ,4, 5, 6, 7, 8, 1, 2]
در کدهای بالا ما اندیسهای بعد از عدد ۳ و قبل از آن را با همدیگر پیوند داده و در یک لیست قرار دادهایم.
def reverse(arr):
return arr[::-1]
if __name__ == '__main__':
arr = [1, 2, 3, 4, 5, 6, 7, 8]
arr = reverse(arr)
print (arr)
# prints [8 ,7, 6, 5, 4, 3, 2, 1]
یک مثال دیگر از این حالت برای معکوس کردن مقدار یک لیست استفاده میشود. منظور از اندیس -1 آخرین اندیس آرایه است و به این معناست که لیست از آنجا شروع شود.
Lambda
Lambda یک تابع ناشناس است که با استفاده از یک عبارت یک خطی قابلیت اجرای یک تابع را میدهد. در واقع Lambda یک شیوه برای تعریف و فراخوانی تابع است که بسیار مختصرتر و سریعتر اتفاق میافتد.
سینتکس کلی:
lambda arguments : expression
مثال:
import math
square_root = lambda x: math.sqrt(x)
# is an equivalant lambda expression for below function
def square_root(x):
return math.sqrt(x)
در مثال بالا ما یک تابع ناشناس را پیادهسازی کردهایم و آن را به متغیر square_root تخصیص دادهایم. در زیر آن هم راه حل معادل آن در روش پایهای را پیادهسازی کردهایم.
Map
Map سناریویی است که ما در آن یک تابع یا Lambda را روی یک رشته از المنتها اعمال میکنیم. البته شما میتوانید این مفهوم را با استفاده از List Comprehension نیز پیادهسازی بکنید:
سینتکس کلی:
map(function , sequence)
- returns an iterable.
مثال:
# Square the numbers in the list.
import math
if __name__ == '__main__':
arr = [1, 2, 3, 4, 5]
arr = list(map(lambda x : x**2, arr))
print (arr)
دلیل استفاده از کلمه list این است که خروجی map را به صورت یک لیست در متغیر arr قرار دهد.
Filter
دستور فیلتر نیز کارکردی شبیه به Map دارد. در دستور فیلتر یک تابع تک تک المانهای یک آرایه را به عنوان ورودی دریافت میکند و اگر نتیجه نهایی True باشد، به یک لیست دیگر اضافه میکند.
سینتکس کلی:
filter(function, sequence)
- returns an iterable.
مثال:
# Print all even numbers in an array.
if __name__ == '__main__':
arr = [1, 2, 3, 4, 5, 6]
arr = list(filter(lambda x : x%2 == 0, arr))
print (arr)
# print [2, 4, 6]
در مثال بالا ما یک فیلتر را اعمال کردیم که در آن تنها اعداد زوج یک آرایه برگشت داده میشود.
Generator
Generatorها راهی ساده برای ایجاد یک المان تکرارپذیر ایجاد میکنند. به صورتی سادهتر باید گفت که Generator یک تابع است که یک شئ تکرارپذیر را برمیگرداند.
قبل از ایجاد چنین تابعی، ما باید به صورت زیر هدفمان را پیادهسازی میکردیم:
# Iterator for next power of two.
class NextPowTwo:
def __init__(self, max_ele = 0):
self.max_ele = max_ele
def __iter__(self):
self.n = 0
return self
def __next__(self):
if self.n <= self.max_ele:
result = 2 ** self.n
self.n += 1
return result
else:
raise StopIteration
if __name__ == '__main__':
it = iter(NextPowTwo(20))
print (next(it)) # prints '1'
print (next(it)) # prints '2'
print (next(it)) # prints '4'
print (next(it)) # prints '8'
اما حال پایتون این کار را برایمان بسیار سادهتر کرده است. با استفاده از Generatorها میتوانیم به صورت زیر کارمان را جلو ببریم:
# Generator for next power of two.
def NextPowTwo(max_ele):
n = 0
while n < max_ele:
yield 2 * n
n += 1
raise StopIteration
obj = NextPowTwo(20)
print (obj.next())
print (obj.next())
print (obj.next())
print (obj.next())
Generatorها با استفاده از همان تعریف عادی توابع پیادهسازی میشوند با این تفاوت که بجای استفاده از return ما در این توابع از yield استفاده میکنیم. اگر یک تابع حداقل یک دستور yield داشته باشد به یک Generator تبدیل میشود. در حالیکه return در یک تابع، باعث میشود که کل فرایند اجرای تابع به اتمام برسد اما yield روند اجرا را متوقف کرده، سپس تمام وضعیتهای موجود را ذخیره میکند. بعد از آن فراخوانی موفقیت آمیز را دوباره انجام میدهد.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید