از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
map()، filter() و reduce() در پایتون با Examples
سرفصلهای مطلب
معرفی
را 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
. نتایج این تابع به ترتیب به لیست اضافه شد.
یک راه زیباتر برای انجام این کار دقیقاً استفاده از لامبدا است:
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
در کنار عنصر بعدی (در این مورد سوم)
این process تکرار می شود تا زمانی که تمام عناصر موجود در دنباله را بررسی کنیم.
آرگومان اختیاری initial
در صورت وجود، در ابتدای این “حلقه” با اولین عنصر در اولین فراخوانی به استفاده می شود function
. به نوعی، initial
عنصر 0مین عنصر است، قبل از اولین عنصر، در صورت ارائه.
reduce()
درک کمی سخت تر از map()
و filter()
، بنابراین بیایید به یک مثال گام به گام نگاه کنیم:
-
ما با یک لیست شروع می کنیم
(2, 4, 7, 3)
و عبور کنیدadd(x, y)
تابع بهreduce()
در کنار این لیست، بدونinitial
ارزش -
reduce()
تماس می گیردadd(2, 4)
، وadd()
برمی گرداند6
-
reduce()
تماس می گیردadd(6, 7)
(نتیجه تماس قبلی بهadd()
و عنصر بعدی در لیست به عنوان پارامتر)، وadd()
برمی گرداند13
-
reduce()
تماس می گیردadd(13, 3)
، وadd()
برمی گرداند16
-
از آنجایی که هیچ عنصر دیگری در دنباله باقی نمانده است،
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