تابع all در پایتون آنچنان قدرتمند است که آن را به کتابخانه داخلی و پیشفرض پایتون اضافه کردهاند. تابع all یکی از کاربردیترین ترفندهای پایتون به حساب میآید و درک نحوه استفاده از این تابع شرطی زنجیرهای میتواند باعث مختصر شدن، انعطافپذیری بیشتر و به اصطلاح «پایتونی شدن» (Pythonic) کدهای برنامه نویسان شود. کاربردها و موارد استفاده ممکن برای تابع all در پایتون محدودیت کمی دارند و بنابراین در این مقاله، برخی از کاربردهای اساسی و تعدادی از موارد پیشرفتهتر به همراه مثال نمایش داده شدهاند. امید است در این مقاله به مخاطبان ثابت شود که چرا همه برنامهنویسان پایتون باید هرچه زودتر نحوه استفاده از تابع all در پایتون را فرا بگیرند.
فیلم آموزشی تابع Any و All در پایتون
تابع all در پایتون چیست؟
تابع all() در پایتون یکی از توابع داخلی و پیشفرض به حساب میآید که تمام یک مجموعه را برای درستی یا True
بودن مقادیر آن مورد ارزیابی قرار میدهد. میتوان از تابع all در پایتون به صورت سینتکس ایستا استفاده کرد یا اینکه پیادهسازی پویاتری را در ترکیب با ویژگیها و قابلیتهایی مثل «لیستهای مفهومی» (List Comprehension) و Generatorها (مولدها) را به همراه آن به کار گرفت. از تابع all در پایتون میتوان به همراه سایر قابلیتها و ترفندهای پایتون برای ساخت گزارههای شرطی کوتاه، واضح و قدرتمند استفاده کرد.
آموزش سریع تابع all در پایتون
در این بخش سعی شده است آموزش تابع all در پایتون به خلاصهترین شکل ممکن ارائه شود تا اگر زمان کافی برای مطالعه کامل این مقاله وجود ندارد، بتوان درک کلی و ابتدایی از چیستی و نحوه استفاده از آن بدست آورد.
تابع all در پایتون تمام یک مجموعه را به طور کامل برای یافتن شرطهایی وارسی میکند که مقدار آنها برابر با True
ارزیابی ميشوند. یعنی اگر ارزش درستی تمام مقادیر یک موجودیت مجموعهوار مثل لیست در پایتون برابر با True باشند، خروجی تابع all هم True
خواهد بود و در غیر این صورت، خروجی تابع all در پایتون False
است. برای درک بهتر این ترفند پایتونی در ادامه مثالی ساده ارائه شده است:
# Have a collection of integers
>>> nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Check all items are integers
>>> all(int(x) for x in nums)
# That's a bingo
True
کاربرد ساده و ابتدایی تابع all در پایتون
زبان برنامه نویسی پایتون شامل انواع تکرارگر (Iterable) بسیاری است که اکثر آنها در ادامه فهرست شدهاند:
- لیست در پایتون
- دیکشنری
- مجموعه
- مولد (Generator)
- رشته در پایتون
- سایر موارد
تابع all در پایتون را میتوان برای هر کدام از انواع داده فوق استفاده کرد. تابع all در پایتون را میتوان تقریباً معادل با این مفهوم در نظر گرفت که به ازای تمام مقادیر در یک لیست بررسی شود آیا ارزش درستی هر عضو برابر با True
است یا خیر؟ در ادامه چند مورد استفاده ابتدایی از تابع all در پایتون به صورت مثالهایی ساده ارائه شدهاند.
۱. ارزیابی ابتدایی درستی با تابع all در پایتون
در این مورد استفاده ساده و پیشپا افتاده از تابع all در پایتون رفتار اصلی و کلیدی این تابع مشخص میشود. رفتار و عملکرد اصلی تابع all به این صورت است که بررسی میشود آیا ارزش تمام اقلام موجود در یک نوع داده تکرارگر True
است یا خیر؟ مثال مربوط به این بخش در ادامه ملاحظه میشود:
# Create a list
l = [0, 1, 2, 3, 4, 5]
all(l)
>>> False
در مثال فوق، تنها عضوی که باعث میشود نتیجه اجرای تابع all روی لیست l
برابر با False
شود، اولین عضو این لیست است؛ زیرا اولین عضو لیست l
مقدار 0
دارد که در منطق بولی ارزش آن برابر با False
است. برای درک بهتر ارزش مقادیر مختلف، در ادامه چند مثال داخل یک قطعه کد ارائه شده است:
# 1.Check the numerical value of False
>>> 0 == False
True
# 2.Check the numerical value of True
>>> 1 == True
True
# 3.Check for other values of True
>>> 1 == True and 2 == True and 3 == True and 4 == True and 5 == True
False
# 4.Remove the 0 element from list, use all
>>> all([1, 2, 3, 4, 5])
True
# 5.Check an empty list
>>> all([])
True
در ادامه توضیحاتی برای هر یک از مثالهای فوق ارائه شده است تا درک آنها سادهتر شود:
- در اولین مثال قطعه کد بالا در خط دوم بررسی شده است که آیا مقدار 0
در پایتون برابر با False
است که خروجی True
خواهد بود. یعنی پاسخ مثبت است و مقدار صفر در پایتون با False در منطق بولی برابری دارد.
- در مثال دوم که در خط ۵ کدهای بالا آمده، نشان داده شده که ارزش درستی عدد 1
در پایتون برابر با True
است.
- با اجرای مثال سوم (خط ۸) مشخص میشود که تنها ارزش عدد 1 برابر با True
است و ارزش درستی سایر اعداد False
میشود. جالب توجه است که نتیجه این مثال با مثال بعدی تناقض دارد.
- در مثال چهارم (خط ۱۱) با استفاده از تابع all بررسی شده است که آیا مقدار تمام مقادیر یک لیست ارزش True
دارند یا خیر؟ برخلاف مثال قبلی، خروجی در این مثال True
است. یعنی با قرار گرفتن چند عدد صحیح بزرگتر از ۲ در یک لیست و اِعمال تابع all روی آنها نتیجه برابر با True
ارزیابی شده؛ این در حالی است که در مثال قبلی حاصل and
شرطهای True
بودن اعداد بزرگتر از 1
برابر با False
بدست آمده است.
- در مثال آخر (خط ۱۴) نیز مشاهده میشود که نتیجه ارزیابی یک لیست خالی با تابع all در پایتون نیز برابر True
است.
مثالهای فوق ممکن است سردرگم کننده به نظر برسند، چون تناقضهایی در آنها دیده میشود. این حس سردرگمی البته چیزی به جز حس شیرین یادگیری چیزهایی جدید نیست. با مراجعه به مستندات پایتون مشخص میشود که:
تابع all در پایتون در صورتی مقدار True
را بازمیگرداند که ارزش تمام اعضای تکرارگر (Iterable) مربوطه برابر با True
باشند یا اینکه آن Iterable هیچ عضوی نداشته و پوچ باشد.
توضیحات فوق که مربوط به مستندات پایتون هستند ممکن است گیج کننده باشد، بنابراین بهتر است به بیان دیگر اینگونه توضیح داده شود که:
خروجی تابع all در پایتون در صورتی True
خواهد بود که تمام عنصرهای نوع تکرارگر مورد نظر هیچکدام Flase
نباشند. به لحاظ منطقی عبارتهای x is not False
(ارزش متغیر فرضی x
برابر با Flase
نیست) و x is True
(ارزش x
برابر با True
است) با هم معادل و یکسان هستند؛ اما x is not False
در این مورد خاص یعنی در شرح نحوه عملکرد تابع all در پایتون واضحتر و قابلفهمتر است.
با درنظر داشتن توضیحات فوق، اکنون بهتر است اولین مثالی که در این مطلب ارائه شد، بار دیگر بررسی شود:
# Create a list l = [0, 1, 2, 3, 4, 5]
>>> all(l)
False
# Create another list
l_2 = [1, 2, 3, 4, 5]
>>> all(l_2)
True
اولین عنصر یعنی عنصر صفرم لیست مربوطه در مثال فوق باعث شده است که خروجی نتیجه اجرای تابع all روی این لیست برابر با False
شود. دلیلش این است که مقدار عدد 0
در پشت پرده با Flase
برابری دارد. با حذف مقدار صفر در لیست بالا، سایر عنصرها مقادیری غیر صفر دارند که معادل با غیر Flase
یا not-Flase هستند.
معمولاً درک کلیت عملکرد هر نوع تابع مبتنی بر منطق دشوار است. مثالهای ارائه شده تا اینجا با هدف بهتر مشخص شدن جزئیات متفاوت تابع all در پایتون ارائه شدند تا بتوان مثالهای پیشرفتهتری که در ادامه آمدهاند را بهتر درک کرد.
معرفی فیلم های آموزش پایتون
در پلتفرم تم آف تقریباً تمام دورههای مرتبط با آموزش پایتون در یک مجموعه آموزشی گردآوری شدهاند. علاقهمندان به برنامه نویسی پایتون و افرادی که میخواهند برنامه نویس پایتون شوند میتوانند برای شروع یادگیری پایتون از دورههای مقدماتی آن استفاده کنند. همچنین، چندین دوره آموزشی پروژهمحور نیز در این مجموعه برای ادامه یادگیری و تقویت مهارت برنامه نویسی پایتون در دسترس قرار دارند. جدیدترین دوره آموزشی این مجموعه دوره ترفندهای پایتون است که در آن ترفندهای استفاده از تابع all در پایتون هم شرح داده شدهاند. در تصویر فوق تنها برخی از دورههای آموزشی پروژهمحور مجموعه آموزش پایتون قابل ملاحظه هستند.
- برای دسترسی به همه آموزش های پایتون تم آف + اینجا کلیک کنید.
کاربردهای پیشرفته تابع all در پایتون
بسیاری از کاربردهای تابع all در پایتون پویایی بیشتری دارند. در بیشتر مواقع میتوان با تابع all از سینتکسهای مفهومی برای بررسی تعدادی زیادی از عضویتها به عنوان یک گزاره شرطی برای اجرای منطقهایی دیگر استفاده کرد. به بیان دیگر، میتوان از سینتکس خلاصه و مختصر در پایتون بهرهمند شد. در این خصوص، میتوان مثال زیر را در نظر گرفت:
from string import printable
# Check if all letters of a string are in the
# string.printable variable (ASCII characters)
if all(x in printable for x in 'hello, world!'):
print("All Letters are ASCII!")
else:
print("Non-ASCII letters found!")
# The result:
All letters as ASCII!
در مثال فوق با استفاده از تابع all بررسی شده است که آیا تمام حروف در رشته “hello, world!”
در متغیر string.printable
قرار دارند یا خیر؟ یعنی بررسی میشود آیا تمام کارکترهای رشته “hello, world!”
از نوع کاراکترهای اسکی (ASCII) هستند یا خیر؟
نکته: متغیر string.printable
برابر با رشته زیر است (البته به غیر از برخی از فضاهای سفید):
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;?@[]^_`{|}~
مثال فوق مورد استفاده و کاربرد سادهای از تابع all در پایتون را نشان میدهد که ممکن است برنامهنویسان در پروژههای خود با مواردی مشابه با آن مواجه شوند. بررسی برای چندین شرط عضویت روشی قدرتمند برای تصمیمگیری در مورد دادههای پیچیده یا پویا است. حال در ادامه مثالی پیچیدهتر ارائه شده است.
مثال تابع all در پایتون برای ترکیب گزاره ها با یکدیگر
در این بخش مثالی آمده که در آن تابع all در ترکیب با یکی دیگر از توابع داخلی پایتون یعنی تابع any به کار گرفته شده است. در این مثال با استفاده از مجموعه دادههایی ساختگی بررسی خواهد شد که آیا تمام کلیدهای اعضای یک دیکشنری حاوی هر یک از اعضای یک لیست هستند یا خیر؟ در واقع در این مثال ابتدا لیستی (با نام colors
) حاوی رشتههایی ایجاد میشود که هر یک بیانگر رنگ فرضی خاصی هستند.
یک لیست هم حاوی اعداد ۱، ۲ و ۳ ساخته شده است. سپس یک دیکشنری ( data
) با ترکیب تصادفی هر یک از این ۲ لیست ایجاد میشود. کلیدهای این دیکشنری ترکیبهای تصادفی دوتایی از لیست colors
هستند. در پایان با استفاده از تابع all در پایتون بررسی میشود که آیا از تمام اعضای لیست colors
در تشکیل کلیدهای دیکشنری استفاده شده است یا خیر؟
# Define a set of values
colors = ['red', 'blue', 'green']
numbers = [1, 2, 3]
# Generate some random data
>>> data = {
choice(colors) + "-" + choice(colors): choice(numbers) * choice(numbers)
for x in range(10)
}
{'blue-blue': 3, 'blue-red': 2, 'red-blue': 2, 'green-green': 6, 'red-green': 1, 'blue-green': 2}
# Check that ALL members in 'data' contain ANY member of 'colors'
>>> all(any(x in y for y in data.keys()) for x in colors)
True
مثال فوق نهتنها مشخص کننده این مسئله است که چگونه میتوان از تابع all در پایتون به صورت پویا استفاده کرد، بلکه نشان دهنده کاربرد و فایده استفاده از گزارههای مفهومی پایتون نیز هست.
برای یادگیری عمیقتر تابع any در پایتون و مشاهده مثالهای بیشتر برای آن، مطالعه مقاله زیر پیشنهاد میشود:
- مقاله مرتبط: تابع any در پایتون — آموزش کاربردی به زبان ساده
مثال تابع all در پایتون برای استخراج آیتم ها و انتقال آن ها به مجموعه دیگر
از متد all در پایتون میتوان برای استخراج زیرمجموعههایی از مجموعهها استفاده کرد که در آنها نیاز به عضویت شرطی وجود دارد. در ادامه مثال مربوط به این مورد با استفاده از دادههای ساختگی ارائه شده است:
# Create some random collection of numbers
num_pairs = [(1, 3), (2, 4), (3, 6, 9), (1, 2, 3, 4), (4, 6, 8)]
# Extract any pair of numbers where only even numbers are present
evens = [x for x in num_pairs if all(n % 2 == 0 for n in x)]
>>> evens
# Results in sub-sets containing
# only all-even values
[(2, 4), (4, 6, 8)]
در مثال فوق از تابع all در پایتون برای بررسی جداسازی تاپلهایی در یک لیست استفاده شده است که تمام مقادیر آنها زوج باشند. برای هر تاپلی که حاوی هیچ مقدار غیر زوجی نباشد، سینتکس مفهومی پایتون آن آیتم را انتخاب خواهد کرد و آن را در مجموعه یا همان لیستی جدید به نام evens
قرار خواهد داد.
ملاحظات پیشرفته تابع all در پایتون
در زمان تست مجموعههای بزرگ برای عضویت اعضای آنها، برخی مسائل و مشکلاتی مربوط به عملکرد وجود دارد. در مثال زیر از تابع all در پایتون برای بررسی لیستی از ۱۰۰ میلیون صفر و یک تولید شده به صورت تصادفی استفاده شده است و بعد با استفاده از تابع all بررسی میشود که آیا تمام اعضای این لیست از نوع عدد صحیح هستند یا خیر؟ پیش از بررسی این موضوع، در برنامه زیر یک کاراکتر از نوع غیر صحیح، یعنی کاراکتر رشتهای ‘z’
هم به انتهای مجموعه مربوطه اضافه شده است.
# Create a list 100MMK 1's or 0's, chosen randomly
import random
nums = list(random.choice([0, 1]) for x in range(10**8))
# Add the letter "z" to the end
nums.append('z')
# Test that all members are numerical
import timeit
>>> timeit.timeit(lambda: all(type(x) == int for x in nums))
# Total Execution Time
5.397376900000005
در قطعه کد بالا موارد زیر انجام شدهاند:
- ابتدا لیستی حاوی ۱۰۰ میلیون عدد ۱ و ۰ با ترتیب تصادفی ایجاد شده است.
- تنها یک کاراکتر رشتهای یعنی ‘z’
به انتهای این لیست اضافه شده است.
- بررسی میشود که آیا تمام آیتمهای موجود در لیست مقادیری از نوع عدد صحیح هستند یا خیر؟
باید توجه شود که زمان اجرای کلی کدهای فوق در حالتی که کاراکتر ‘z’
در انتهای دنباله مربوطه آمده، تقریباً برابر با ۵٫۴ ثانیه است. این زمان تخمینی نشان میدهد که تابع all در پایتون قبل از حصول اطمینان از اینکه همه عناصر لیست مربوطه از نوع عدد صحیح هستند، نیاز دارد تا تمام اعضای آن را به صورت تک به تک بررسی کند و روی آنها تکرار انجام دهد.
حالا به فرض اگر کاراکتر ‘z’
در ابتدای لیست قرار داشته باشد، دیگر منطقی نیست که تمام ۱۰۰ میلیون عضو این لیست تکبهتک تا انتها بررسی شوند. اما سازندگان پایتون باهوش هستند و به همین دلیل تابع all را بهگونهای طراحی کردهاند که به محض برخورد با یک مقدار غیر True
بررسی باقی مقادیر متوقف میشود و همه عنصرها بهطور کامل بررسی نمیشوند. برای نشان دادن این موضوع، مثال فوق دوباره این بار در حالتی اجرا شده است که کاراکتر ‘z’
در ابتدای لیست مربوطه قرار داده میشود:
# Create a list 100MM 1's or 0's, chosen randomly
import random
nums = list(random.choice([0, 1]) for x in range(10**8))
# Add the letter "z" to the start
nums.insert(0, 'z')
# Test that all members are numerical
import timeit
timeit.timeit(lambda: all(type(x) == int for x in nums), number=1)
# A reeaaly small value
2.600000001962144e-06
البته دانستن این نکته درباره تابع all در پایتون چندان ضرورتی ندارد. اما با کسب آگاهی از نحوه توسعه توابع در پایتون و سایر زبانهای برنامه نویسی میتوان درک بهتری از آنها بدست آورد. مخصوصاً در مورد مشکلات مربوط به کیفیت عملکرد (زمان اجرا) این مسئله بسیار اهمیت دارد و میتوان بهتر مشخص کرد که در چه مواقعی بهتر است از چه توابعی استفاده شود.
جمعبندی
تابع all در پایتون یکی از پرکاربردترین ابزارها و ترفندهای پایتون به حساب میآید. طبق تجربه میتوان گفت که امکان بررسی دستهای وضعیت درستی بهطور روزانه بسیار کاربردی و مفید است. سایر زبانهای برنامه نویسی هم به نوعی قابلیتهای مشابهی را ارائه میدهند، اما تعداد کمتری از آنها به صورت از پیش آماده در سینتکس اصلی خود امکاناتی به این شکل و با این سطح از عملکرد مطلوب را ارائه میدهند. در ترکیب با generatorها، کدهای مفهومی و کمی تخیل تابع all میتواند کمک بزرگی به پیادهسازی قابلیتهای مورد نیاز در برنامهها بهگونهای بهینهتر و کارامدتر بکند.