وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

map()، filter() و reduce() در پایتون با Examples

0 97
زمان لازم برای مطالعه: 5 دقیقه


معرفی

را map()، filter() و reduce() توابع کمی برنامه نویسی تابعی را به پایتون می آورند. هر سه اینها توابع راحتی هستند که می توانند با List Comprehension یا حلقه ها جایگزین شوند، اما رویکردی ظریف تر و کوتاه تر برای برخی مشکلات ارائه می دهند.

قبل از ادامه، به چند نکته می پردازیم که قبل از مطالعه روش های ذکر شده باید با آنها آشنا باشید:

تابع/روش ناشناس یا لامبدا چیست؟

یک متد ناشناس متدی بدون نام است، یعنی به یک شناسه محدود نمی شود مانند زمانی که یک متد را با استفاده از آن تعریف می کنیم. def method:.

توجه داشته باشید: اگرچه اکثر مردم از این اصطلاحات استفاده می کنند “عملکرد ناشناس” و “تابع لامبدا” به جای یکدیگر – آنها یکسان نیستند. این اشتباه به این دلیل اتفاق می افتد که در اکثر زبان های برنامه نویسی لامبدا وجود دارد هستند ناشناس و همه توابع ناشناس هستند لامبدا این مورد در پایتون نیز وجود دارد. بنابراین، ما در این مقاله بیشتر به این تمایز نخواهیم پرداخت.

نحو یک تابع لامبدا (یا عملگر لامبدا) چیست؟

lambda arguments: expression

لامبدا را به عنوان روش های تک خطی بدون نام در نظر بگیرید. آنها عملاً مانند هر روش دیگری در پایتون کار می کنند، به عنوان مثال:

def add(x,y):
    return x + y

قابل ترجمه به:

lambda x, y: x + y

لامبداها با متدهای معمولی پایتون متفاوت هستند زیرا می توانند فقط یک عبارت داشته باشند، نمی توانند حاوی هیچ عبارت باشند و نوع بازگشت آنها یک است. function هدف – شی. بنابراین خط کد بالا دقیقاً مقدار را بر نمی گرداند x + y اما تابعی که محاسبه می کند x + y.

چرا لامبداها مرتبط هستند map()، filter() و reduce()?

هر سه این روش ها انتظار دارند الف function شی به عنوان اولین آرگومان این function شی می تواند یک متد از پیش تعریف شده با نام (مانند def add(x,y)).

اگرچه، اغلب، توابع به map()، filter()، و reduce() آنهایی هستند که شما فقط یک بار استفاده می کنید، بنابراین اغلب هیچ فایده ای برای تعریف یک تابع قابل ارجاع وجود ندارد.

برای جلوگیری از تعریف یک تابع جدید برای متفاوت خود map()/filter()/reduce() نیازها – راه حل ظریف تر استفاده از یک عملکرد کوتاه، یکبار مصرف و ناشناس است که فقط یک بار و دیگر هرگز از آن استفاده نخواهید کرد – لامبدا.

تابع map().

را map() تابع از طریق تمام آیتم های تکراری داده شده تکرار می شود و آن را اجرا می کند function ما به عنوان استدلال تصویب کردیم روی هر یک از آنها.

نحو عبارت است از:

map(function, iterable(s))

ما می توانیم پس از عبور از هر تعداد شی تکرار شونده که بخواهیم عبور دهیم function می خواهیم استفاده کنیم:


def starts_with_A(s):
    return s(0) == "A"

fruit = ("Apple", "Banana", "Pear", "Apricot", "Orange")
map_object = map(starts_with_A, fruit)

print(list(map_object))

این کد نتیجه خواهد داد:

(True, False, False, True, False)

همانطور که می بینیم، ما به لیست جدیدی رسیدیم که در آن تابع است starts_with_A() برای هر یک از عناصر موجود در لیست ارزیابی شد fruit. نتایج این تابع به ترتیب به لیست اضافه شد.

پیشنهاد می‌کنیم بخوانید:  روش دریافت JSON از URL در پایتون

یک راه زیباتر برای انجام این کار دقیقاً استفاده از لامبدا است:

fruit = ("Apple", "Banana", "Pear", "Apricot", "Orange")
map_object = map(lambda s: s(0) == "A", fruit)

print(list(map_object))

ما همان خروجی را دریافت می کنیم:

(True, False, False, True, False)

توجه داشته باشید: ممکن است متوجه شده باشید که ما بازیگران را انتخاب کرده ایم map_object به یک لیست به print ارزش هر عنصر ما این کار را به دلیل تماس انجام دادیم print() روی یک لیست خواهد شد print مقادیر واقعی عناصر صدا زدن print() روی map_object خواهد شد print در عوض آدرس های حافظه مقادیر.

را map() تابع را برمی گرداند map_object نوع، که یک تکرارپذیر است و می‌توانیم نتایج را به این صورت چاپ کنیم:

for value in map_object:
    print(value)

اگر شما می خواهید map() تابع برای برگرداندن یک لیست به جای آن، می توانید آن را هنگام فراخوانی تابع ارسال کنید:

result_list = list(map(lambda s: s(0) == "A", fruit))

تابع filter().

شبیه به map()، filter() الف می گیرد function شی و یک تکرار شونده و یک لیست جدید ایجاد می کند.

همانطور که از نامش پیداست، filter() یک لیست جدید را تشکیل می دهد که فقط شامل عناصری است که شرایط خاصی را برآورده می کند function ما بازده گذشت True.

نحو عبارت است از:

filter(function, iterable(s))

با استفاده از مثال قبلی، می بینیم که لیست جدید فقط حاوی عناصری است که starts_with_A() تابع برمی گردد True:


def starts_with_A(s):
    return s(0) == "A"

fruit = ("Apple", "Banana", "Pear", "Apricot", "Orange")
filter_object = filter(starts_with_A, fruit)

print(list(filter_object))

با اجرای این کد، لیست کوتاه تری ایجاد می شود:

('Apple', 'Apricot')

یا با استفاده از لامبدا بازنویسی شود:

fruit = ("Apple", "Banana", "Pear", "Apricot", "Orange")
filter_object = filter(lambda s: s(0) == "A", fruit)

print(list(filter_object))

چاپ همان خروجی را به ما می دهد:

('Apple', 'Apricot')

تابع ()reduce

reduce() متفاوت از map() و filter(). این یک لیست جدید بر اساس برمی گرداند روی را function و تکراری ما گذشت. در عوض، یک مقدار واحد را برمی گرداند.

همچنین در پایتون 3 reduce() دیگر یک تابع داخلی نیست و می توان آن را در functools مدول.

نحو عبارت است از:

reduce(function, sequence(, initial))

reduce() با فراخوانی کار می کند function ما برای دو مورد اول در دنباله گذشتیم. نتیجه برگردانده شده توسط function در تماس دیگری به استفاده می شود function در کنار عنصر بعدی (در این مورد سوم)

پیشنهاد می‌کنیم بخوانید:  چگونه با پایتون یک Job Board Scraper بسازیم

این process تکرار می شود تا زمانی که تمام عناصر موجود در دنباله را بررسی کنیم.

آرگومان اختیاری initial در صورت وجود، در ابتدای این “حلقه” با اولین عنصر در اولین فراخوانی به استفاده می شود function. به نوعی، initial عنصر 0مین عنصر است، قبل از اولین عنصر، در صورت ارائه.

reduce() درک کمی سخت تر از map() و filter()، بنابراین بیایید به یک مثال گام به گام نگاه کنیم:

  1. ما با یک لیست شروع می کنیم (2, 4, 7, 3) و عبور کنید add(x, y) تابع به reduce() در کنار این لیست، بدون initial ارزش

  2. reduce() تماس می گیرد add(2, 4)، و add() برمی گرداند 6

  3. reduce() تماس می گیرد add(6, 7) (نتیجه تماس قبلی به add() و عنصر بعدی در لیست به عنوان پارامتر)، و add() برمی گرداند 13

  4. reduce() تماس می گیرد add(13, 3)، و add() برمی گرداند 16

  5. از آنجایی که هیچ عنصر دیگری در دنباله باقی نمانده است، reduce() برمی گرداند 16

تنها تفاوت، اگر ما داده بودیم initial ارزش یک مرحله اضافی بود – 1.5. جایی که reduce() تماس بگیرید add(initial, 2) و از آن مقدار بازگشتی در مرحله استفاده کنید 2.

بیایید جلو برویم و از آن استفاده کنیم reduce() تابع:

from functools import reduce

def add(x, y):
    return x + y

list = (2, 4, 7, 3)
print(reduce(add, list))

با اجرای این کد به دست می آید:

16

باز هم، این را می توان با استفاده از لامبدا نوشت:

from functools import reduce

list = (2, 4, 7, 3)
print(reduce(lambda x, y: x + y, list))
print("With an initial value: " + str(reduce(lambda x, y: x + y, list, 10)))

و کد به این نتیجه می رسد:

16
With an initial value: 26

نتیجه

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

این ابزارها را مجبور نکنید زیرا “شما می توانید”، زیرا اغلب می تواند منجر به کدهای ناخوانا شود که نگهداری آن سخت است. فقط زمانی از آنها استفاده کنید که کاملاً مشخص باشد که چه اتفاقی می افتد روی به محض اینکه به تابع یا عبارت لامبدا نگاه می کنید.

اگر متوجه شدید که در حال تقلا برای تطبیق منطق لازم در یک منطق هستید map() تابع، یا یک عبارت لامبدا، خیلی بهتر است که فقط یک روش برای حلقه/تعریف شده کمی طولانی‌تر بنویسید و بعداً از سردرگمی غیر ضروری جلوگیری کنید.

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-17 11:59:03

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید