در آموزشهای گذشته با دیتا تایپ لیست در زبان برنامهنویسی پایتون آشنا شدیم و گفتیم که دیتا تایپ تاپل نیز در این زبان قابلیتهایی همچون دیتا تایپ لیست دارا است و به منظور ذخیرۀ مجموعهای از دادههای غیرهمنوع مورد استفاده قرار میگیرد با این تفاوت که محتوای آبجکتی از جنس تاپل را نمیتوان تغییر داد. در واقع، دیتا تایپ تاپل را میتوان به منظور ذخیرۀ دیتایی با سطح دسترسی به اصطلاح Read-only مورد استفاده قرار داد؛ به عبارت بهتر، ذخیرۀ دیتا با بهکارگیری دیتا تایپ تاپل منجر بدین میشود تا سطح دسترسی به دیتای مد نظر محدود شده و بدین ترتیب امکان تغییر، حذف یا افزودن دیتای جدید در سایر نقاط برنامه وجود نداشته باشد.
اولین و سادهترین تفاوت دیتا تایپ تاپل نسبت به نوع دادۀ لیست این است که به منظور تعریف آبجکتهایی از جنس تاپل به جای علائم [ ] از علائم () استفاده میکنیم که برای آشنایی بیشتر با نحوۀ ساخت آبجکتی از جنس تاپل، مثال زیر را مد نظر قرار میدهیم:
>>> colorTuple = ("red", "green", "blue", "yellow")در دستور فوق، متغیری به نام colorTuple از جنس تاپل تعریف کردهایم با این تفاوت که اعضای آن به جای قرار گرفتن در میان علائم [ ] در میان () قرار گرفتهاند که برای حصول اطمینان از نوع دادۀ مد نظر نیز فانکشن از پیش تعریفشدۀ ()type را با آرگومان ورودی colorTuple فراخوانی میکنیم:
>>> type(colorTuple)
<class 'tuple'>همانطور که ملاحظه میشود، اجرای دستور فوق منجر به ریترن شدن کلاس مربوط به نوع آبجکت مد نظر تحت عنوان tuple در خروجی شده است. حال در ادامۀ این آموزش قصد داریم تا به تشریح ویژگیهای این دیتا تایپ پرداخته و برخی فانکشنهای به اصطلاح Built-in در زبان پایتون را به منظور اِعمال روی آبجکتهایی از جنس تاپل معرفی کنیم.
نحوۀ دسترسی به محتوای تاپل
نحوۀ دسترسی به محتوای آبجکتی از جنس تاپل همانند دیتا تایپ لیست میباشد که جهت کسب اطلاعات بیشتر میتوانید به آموزش آشنایی نحوۀ دسترسی به محتوای لیست در زبان برنامهنویسی پایتون مراجعه کنید. همچنین همانطور که در ابتدای آموزش اشاره کردیم، دیتا تایپ تاپل تغییرناپذیر بوده و از همین روی فراخوانی فانکشنهای از پیش تعریفشدهای همچون ()sort و ()append یا ()remove در آنها هیچ تغییری اِعمال نمیکنند.
نحوۀ ویرایش محتوای تاپل
در این بخش قصد داریم تا به بررسی این موضوع بپردازیم که منظور از تغییرناپذیر بودن دیتا تایپ تاپل چیست و چرا نمیتوان محتوای آن را تغییر داد که برای درک بهتر این مفهوم در مثال زیر سعی کردهایم تا اِلِمان اول از آبجکت مربوط به مثال قبل را تغییر دهیم:
>>> colorTuple[0] = "orange"
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
colorTuple[0]='orange'
TypeError: 'tuple' object does not support item assignment
در کد فوق، قصد داریم تا مقدار اِلِمان اول از آبجکت colorTuple را تغییر دهیم و از آنجایی که اندیسگذاری آبجکتهایی از جنس تاپل و لیست از عدد صفر شروع میشود، به منظور دسترسی به اِلِمان اول عدد 0 را به کار بردهایم که در نتیجۀ اجرای این دستور با اروری مواجه میشویم مبنی بر اینکه آبجکتی از جنس تاپل تغییرناپذیر بوده و نمیتوان مقدار منتسب به آن را تغییر داد اما در عین حال میتوان آبجکتی جدید از جنس تاپل را با استفاده از به اصطلاح Concate (الحاق) دو یا چند آبجکت تاپل دیگر ایجاد کرد که برای این منظور کد زیر را مد نظر قرار میدهیم:
>>> tupleOne = ("red", "green", "blue", "yellow")
>>> tupleTwo = ("orange", "pink")
>>> newColorTuple = tupleOne + tupleTwo
>>> newColorTuple
('red', 'green', 'blue', 'yellow', 'orange', 'pink')
در کد فوق، ابتدا آبجکتی از جنس تاپل تحت عنوان tupleOne تعریف کرده و یکسری اِلِمان را به آن منتسب کردهایم و در ادامه آبجکتی دیگر از جنس تاپل تحت عنوان tupleTwo تعریف کردهایم که دو اِلِمان دیگر از جنس استرینگ را به این آبجکت اختصاص دادهایم. حال در صورتی که بخواهیم تا مقادیر اِلِمانهای هر دو تاپل را با هم کانکت کنیم، از عملگر + استفاده میکنیم و همانطور که ملاحظه میکنید، عملگر + را به منظور الحاق مقادیر اِلِمانهای دو تاپل tupleOne و tupleTwo به کار گرفتهایم و در ادامه گفتهایم آبجکت تاپل جدید در متغیری تحت عنوان newColorTuple نگهداری شود.
در واقع، نحوۀ کار این عملگر در الحاق دو آبجکت از جنس تاپل بدین صورت است که اِلِمانهای مربوط به آبجکت تاپل دوم را به انتهای اِلِمانهای مربوط به آبجکت اول اضافه کرده و آبجکتی جدید از جنس تاپل ایجاد میکند و نهایتاً در مثال فوق، مقادیر اِلِمانهای مربوط به تاپل جدید به متغیر newColorTuple منتسب میشود و در سطر آخر نیز میبینیم که محتوای ذخیرهشده در آبجکت تاپل جدید برابر با نتیجۀ حاصل از الحاق اِلِمانهای دو تاپل مذکور میباشد.
نحوۀ حذف برخی اِلِمانهای تاپل
همانطور که اشاره کردیم، دیتا تایپ تاپل تغییرناپذیر است و از همین روی نمیتوان اِلِمان خاصی را از آن حذف کرد اما این در حالی است که امکان حذف خود آبجکت تاپل با بهکارگیری کیورد del فراهم میباشد که برای این منظور کد زیر را در نظر میگیریم:
>>> del newColorTuple
>>> newColorTuple
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
newColorTuple
NameError: name 'newColorTuple' is not defined
همانطور که مشاهده میکنید، ابتدا کیورد del را نوشته و در ادامه آبجکت تاپل مربوط به مثال قبل را آوردهایم و بدین ترتیب قصد داریم تا کل آبجکت مذکور به همراه تمامی اِلِمانهای ذخیرهشده در آن را حذف کنیم که با اجرای این دستور تاپل مد نظر حذف میشود (در سطر بعد شناسۀ این آبجکت را تایپ کرده و قصد داریم تا بدین وسیله محتوای آن را در خروجی ریترن کنیم و همانطور که انتظار میرود اجرای این دستور منجر به اروری شده است مبنی بر اینکه آبجکتی با این شناسه موجود نمیباشد چرا که پیش از این از روی حافظه حذف شده است.)
اِعمال عملیات ریاضیاتی پایه روی آبجکتهایی از جنس تاپل
برخی اپراتورهای ریاضیاتی همچون + و * را میتوان بر روی دو یا چند آبجکت از جنس تاپل اِعمال کرد که در ادامه به تشریح نحوۀ عملکرد این اپراتورها روی چنین آبجکتهایی میپردازیم:
- اپراتور Plus: اپراتور + به منظور کانکت کردن اِلِمانهای دو یا چند آبجکت تاپل مورد استفاده قرار میگیرد که با نحوۀ پیادهسازی آن در مبحث مربوط به ساخت آبجکتی جدید از جنس تاپل با الحاق اِلِمانهای دو آبجکت آشنا شدیم.
- اپراتور Multiply: عملگر * بدین صورت مورد استفاده قرار میگیرد که یک آبجکت از جنس تاپل را در یک عدد طبیعی ضرب میکنیم و نتیجۀ آن ایجاد آبجکتی جدید از جنس تاپل میباشد که در آن تمامی اِلِمانهای آبجکت پیشین به تعداد عدد مد نظر تکرار شده است. برای درک بهتر این موضوع، کدهای زیر را مد نظر قرار میدهیم:
>>> newTuple = tupleTwo * 2
>>> print(newTuple)
('orange', 'pink', 'orange', 'pink')
>>> len(newTuple)
4
در کد فوق، گفتهایم تمامی اِلِمانهای تاپل مربوط به مثال قبل که در متغیری تحت عنوان tupleTwo نگهداری میشوند، به تعداد دو مرتبه تکرار شده و به متغیری جدید به نام newTuple منتسب شوند (توجه داشته باشیم که محتوای مربوط به آبجکت تاپل tupleTwo تغییری نخواهد کرد.) و در ادامه محتوای منتسب به متغیر newTuple را در خروجی چاپ کردهایم و همانطور که انتظار میرفت دو اِلِمان مربوط به تاپل tupleTwo در آبجکت تاپل newTuple دو مرتبه تکرار شدهاند و در نهایت هم این آبجکت را به عنوان آرگومان ورودی به فانکشن از پیش تعریفشدۀ ()len دادهایم که تعداد آیتمهای ذخیرهشده در آبجکت مد نظر را در خروجی ریترن میکند و از همین روی عدد 4 در خروجی چاپ شده است.
آشنایی با مفاهیم Packing و Unpacking
در زبان برنامهنویسی پایتون قابلیتی برای آبجکتهایی از جنس تاپل تعریف شده است که در آن با تعریف یک آبجکت از نوع دادۀ تاپل سپس انتساب آن به مجموعهای از متغیرها میتوان هر یک از اِلِمانهای تاپل اول را به متغیر متناظرشان اختصاص داد. در واقع، به پروسۀ تعریف یک آبجکت از جنس تاپل اصطلاحاً Packing گفته شده و اختصاص مقادیر اِلِمانهای این تاپل به مجموعهای متغیرهای متناظرشان به اصطلاح Unpacking نامیده میشود که برای درک بهتر این موضوع مثال زیر را مد نظر قرار میدهیم:
>>> tupleOne = ("Urmia University of Technology", 9011, "Information Technolog")
>>> (college, studentNumber, fieldOfStudy) = tupleOne
>>> college
'Urmia University of Technology'
>>> studentNumber
9011
>>> fieldOfStudy
'Information Technology'
در کد فوق، آبجکتی از نوع تاپل تعریف کرده و مقادیری از جنس استرینگ و عدد را بدان اختصاص دادهایم و در ادامه آبجکت مذکور را به متغیری تحت عنوان tupleOne منتسب کردهایم و همانطور که پیشتر اشاره کردیم، این فرآیند به اصطلاح Packing نام دارد. حال در سطر بعد هر یک از اِلِمانهای مربوط به آبجکت تاپل ایجادشده را در طی یک پروسۀ Unpacking به مجموعهای از متغیرهای متناظرشان در سمت چپ = منتسب کردهایم و میبینیم که هر یک از اِلِمانهای آبجکت tupleOne به متغیر متناظرشان در سمت چپ اپراتور = منتسب شدهاند.
| نکته |
به منظور انتساب هر یک از اِلِمانهای آبجکت تاپل به مجموعهای از متغیرها میباید حتماً تعداد اِلِمانهای آبجکت مد نظر با تعداد متغیرها برابر باشند. |
اما در عین حال و با توجه به آنچه در نکتهٔ بالا بدان اشاره کردیم، میتوان شرایطی را در نظر گرفت که در آن تعداد متغیرها در سمت چپ اپراتور = با تعداد اِلِمانهای آبجکت تاپل برابر نباشد بدین صورت که از علامت * در کنار شناسۀ متغیر مد نظر استفاده کرده و بدین ترتیب میتوان به تعداد بیش از یک اِلِمان از آبجکت تاپل مد نظر را به متغیر مربوطه منتسب کرد که در همین راستا توجه شما را به مثال زیر جلب میکنیم:
>>> tupleOne = (10, "Sokan", "Academy", 50)
>>> (x, y, *z) = tupleOne
>>> x
10
>>> y
'Sokan'
>>> z
['Academy', 50]
در کد فوق، آبجکتی از جنس تاپل با مقادیری از استرینگ و عدد را تعریف کرده و آن را به متغیری تحت عنوان tupleOne منتسب کردهایم و در ادامه گفتهایم اِلِمان اول از آبجکت تاپل که برابر با عدد 10 است به متغیر x اختصاص یافته و اِلِمان دوم از این آبجکت معادل استرینگ «Sokan» نیز به متغیر y منتسب شود و در ادامه گفتهایم سایر اِلِمانهای مربوط به آبجکت tupleOne به متغیر z منتسب شوند. همانطور که در کد فوق میبینید، محتوای هر یک از متغیرهای x و y به ترتیب برابر با مقادیر متناظرشان از تاپل مذکور بوده و سایر اِلِمانهای آن نیز به متغیر z منتسب شدهاند. به عنوان یک نمونه مثال دیگر داریم:
>>> tupleOne = (10, "Sokan", "Academy", 50)
>>> (*x, y, z) = tupleOne
>>> x
[10, 'Sokan']
>>> y
'Academy'
>>> z
50
در کد فوق، گفتهایم مقادیر هر یک از اِلِمانهای آبجکت tupleOne بدین ترتیب به اصطلاح Unpack شوند که مقادیر مربوط به دو اِلِمان آخر از این آبجکت به ترتیب به هر یک از متغیرهای y و z منتسب شده و سایر اِلِمانهای آن نیز به متغیر x اختصاص داده شوند و بدین ترتیب میبینیم که استرینگ «Academy» و عدد 50 به ترتیب به متغیرهای y و z اختصاص یافته و مقادیر مربوط به سایر اِلِمانهای این آبجکت نیز به متغیر x منتسب شدهاند.
زبان برنامهنویسی پایتون یکسری فانکشن از پیش تعریفشده دارا است که برخی از پرکاربردترین آنها را در آموزش معرفی برخی از پرکاربردترین فانکشنهای Built-in در زبان برنامهنویسی پایتون معرفی کردیم. حال در ادامه قصد داریم تا برخی از دیگر فانکشنهای Built-in در این زبان را معرفی کنیم که به منظور اِعمال روی آبجکتهایی از جنس تاپل در نظر گرفته شدهاند.
کاربرد فانکشنهای ()max و ()min
فانکشن ()max دارای یک پارامتر ورودی میباشد که جهت ریترن کردن بزرگترین مقدار از میان اِلِمانهای آبجکتی از جنس تاپل مورد استفاده قرار میگیرد و برای این منظور نیز میباید آبجکت مد نظر را به عنوان آرگومان ورودی به آن بدهیم که برای درک بهتر کاربرد این فانکشن مثال زیر را مد نظر قرار میدهیم:
>>> tupleOne = (1, 20, 300)
>>> tupleTwo = ("orange", "pink")
>>> max(tupleTwo)
'pink'
>>> max(tupleOne)
300
>>> min(tupleOne)
1در تفسیر کد فوق باید گفت که در ابتدا دو آبجکت از جنس تاپل تحت عناوین tupleOne و tupleTwo تعریف کردهایم که برای تاپل اول یکسری مقدار عددی را اختصاص دادهایم و تاپل دوم نیز متشکل از دو استرینگ میباشد و در ادامه هر یک از آبجکتهای مذکور را به عنوان آرگومان ورودی به فانکشن ()max دادهایم. همانطور که میبینیم، خروجی حاصل از فراخوانی فانکشن ()max به ازای آبجکت تاپلی متشکل از مقادیر استرینگ برابر با «pink» میباشد و نحوۀ مقایسۀ اِلِمانهایی با دیتا تایپ استرینگ بدین صورت است که هر کاراکتر بر اساس مقدار متناظر آن در کدگذاری ASCII با کاراکتر دیگر از سایر استرینگهای تاپل مقایسه میشوند.
در واقع، در این مثال، نحوۀ مقایسۀ مقادیر استرینگ بدین صورت است کاراکتر اول از استرینگ «orange» با کاراکتر اول از استرینگ «pink» مقایسه میشوند و چنانچه مقادیر هر یک از دو کاراکتر در کدگذاری ASCII برابر باشند، به سراغ کاراکترهای دوم رفته و این روند ادامه مییابد تا زمانی که به اولین کاراکتری برسیم که مقدار متناظر آن در کدگذاری ASCII بزرگتر از کاراکتر مربوط به استرینگ دوم باشد که در نهایت استرینگی به عنوان مقدار بزرگتر در خروجی ریترن میشود که اولین کاراکتر با مقدار متناظر بزرگتر در کدگذاری ASCII را داشته باشد که برای درک بهتر نحوۀ کدگذاری ASCII میتوانید به آموزش آشنایی با استانداردهای کدگذاری ASCII و Unicode مراجعه کنید.
به علاوه، فراخوانی فانکشن ()max به ازای آرگومان ورودی تاپل متشکل از مقادیر عددی نیز بزرگترین مقدار را از میان اِلِمانهای تاپل مد نظر در خروجی ریترن میکند که از همین روی عدد 300 در خروجی ریترن شده است.
فانکشن ()min نیز عملکردی مشابه فانکشن ()max دارا است با این تفاوت که فراخوانی آن با آرگومان ورودی مربوط به هر یک از آبجکتهای تاپل منجر بدین میشود تا در مقایسههای انجامشده مابین اِلِمانهای مختلف آیتم مربوط به کوچکترین مقدار در خروجی ریترن شود.
کاربرد فانکشن ()tuple
این فانکشن نیز قابلیتی دارا است تا یک آرگومان ورودی از نوع لیست یا استرینگ را گرفته و به آبجکتی جدید از جنس تاپل مبدل سازد. برای مثال، کد زیر را مد نظر قرار میدهیم:
>>> listA = [1, 2, 3, 4, 5]
>>> tupleB = tuple(listA)
در کد فوق، آبجکتی از جنس لیست را با بهکارگیری علائم [ ] تعریف کرده و یکسری مقادیر عددی به آن اختصاص داده و در نهایت آبجکت تعریفشده را به متغیری تحت عنوان listA منتسب کردهایم و در ادامه فانکشن ()tuple را فراخوانی کرده و آبجکت listA را به عنوان آرگومان ورودی به آن دادهایم و نتیجه حاصل از این فراخوانی را به متغیری تحت عنوان tupleB منتسب کردهایم. در واقع، با اجرای دستور فوق آبجکتی جدید از جنس تاپل ساخته شده و به متغیر tupleB منتسب میشود و این در حالی است که دیتا تایپ آبجکت listA تغییری نخواهد کرد که برای بررسی این موضوع خروجیهای زیر را مد نظر قرار میدهیم:
>>> type(listA)
<class 'list'>
>>> type(tupleB)
<class 'tuple'>همانطور که مشاهده میشود، هر یک از آبجکتهای listA و tupleB به ترتیب متعلق به کلاسهای list و tuple میباشند بدین معنی که میتوان با فراخوانی فانکشن ()tuple با آرگومانهای ورودی از جنس لیست و استرینگ آبجکتی جدید با نوع دادۀ تاپل ایجاد کرد. در ادامه مثالی در ارتباط با فراخوانی این فانکشن با یک آرگومان ورودی از جنس استرینگ را مد نظر قرار میدهیم:
print(tuple("SokanAcademy"))
('S', 'o', 'k', 'a', 'n', 'A', 'c', 'a', 'd', 'e', 'm', 'y')
همانطور که میبینیم، فراخوانی فانکشن ()tuple با آرگومان ورودی از جنس استرینگ «SokanAcademy» منجر به ایجاد آبجکتی جدید از جنس تاپل شده است که این آبجکت متشکل از تمامی کاراکترهای استرینگ مربوط به آرگومان ورودی میباشد.
کاربرد فانکشن ()count
این فانکشن یک پارامتر ورودی میگیرد و به منظور شمارش تعداد دفعات تکرار هر یک از اِلِمانهای تشکیلدهندۀ آبجکت تاپل مد نظر مورد استفاده قرار میگیرد که برای درک بهتر نحوۀ کار این فانکشن، مثال زیر را مد نظر قرار میدهیم:
>>> tupleOne = (1, "SokanAcademy", 3, "sokanacademy", 5, 5)
>>> tupleOne.count(5)
2
>>> tupleOne.count('SokanAcademy')
1
در کد فوق، آبجکتی از جنس تاپل با مقادیر اِلِمانهایی از دو دیتا تایپ عدد و استرینگ را تعریف کرده و آن را به متغیری تحت عنوان tupleOne منتسب کردهایم و در سطر بعد فانکشن ()count را روی آبجکت تعریفشده با آرگومان ورودی مربوط به آیتم عدد 5 از آبجکت تاپل مربوطه فراخوانی کردهایم و بدین ترتیب تعداد تکرار عدد 5 در این تاپل در خروجی ریترن میشود که میبینیم عدد 2 در معرض دیدمان قرار میگیرد.
در ادامه قصد داریم تا فانکشن ()count تعداد تکرار استرینگ «SokanAcademy» را در خروجی ریترن کند که برای این منظور استرینگ مذکور را به عنوان آرگومان ورودی به آن میدهیم و میبینیم که این فانکشن مابین دو استرینگ «SokanAcademy» و «sokanacademy» تمایز قائل شده و تعداد تکرار آن را برابر با عدد 1 در نظر میگیرد. همچنین میتوان با بهکارگیری کیورد in بررسی کرد که آیتم مد نظر در آبجکت تاپل مربوطه وجود دارد یا خیر که برای این منظور داریم:
tupleOne = (1, "SokanAcademy", 3, "sokanacademy", 5, 5)
if "SokanAcademy" in tupleOne:
print("Yes, SokanAcademy is in this tuple.")
در کد فوق، آبجکتی از جنس تاپل تعریف کرده و آن را به متغیری به نام tupleOne منتسب کردهایم و در ادامه گفتهایم چنانچه استرینگ «SokanAcademy» در آبجکت منتسب به متغیر tupleOne وجود داشته باشد، استرینگ «.Yes, SokanAcademy is in this tuple» در خروجی چاپ شود که نتیجۀ حاصل از اجرای کد فوق به صورت زیر خواهد بود:
Yes, SokanAcademy is in this tuple.
در واقع، آرگومان ورودی فانکشن ()print استرینگ «.Yes, SokanAcademy is in this tuple» میباشد که با برقرار بودن دستور if یا به عبارتی وجود اِلِمانی از نوع استرینگ «SokanAcademy» در تاپل tupleOne در خروجی چاپ شده است.
کاربرد فانکشن ()index
این فانکشن دارای یک پارامتر ورودی بوده و اندیس مربوط آیتم مد نظر از آبجکت تاپل متناظر را در خروجی ریترن میکند:
>>> tupleOne.index('SokanAcademy')
1در کد فوق، فانکشن از پیش تعریفشدۀ ()index را روی آبجکت tupleOne با آرگومان ورودی مربوط به اِلِمان مد نظر از آبجکت تاپل مربوط به مثال قبل فراخوانی کردهایم و در نهایت اندیس مربوط به آیتم «SokanAcademy» از آبجکت متناظر برابر با عدد 1 در خروجی ریترن شده است.
به طور کلی، در این آموزش به معرفی دیتا تایپ تاپل پرداخته و گفتیم که بر خلاف دیتا تایپ لیست، به منظور ذخیرۀ دیتایی بدون نیاز به اِعمال تغییر روی آن مورد استفاده قرار میگیرد که از جمله تفاوتهای دیگر این دو دیتا تایپ میتوان گفت که استفاده از دیتا تایپ تاپل به منظور ذخیره و نگهداری دیتا در برنامههای بزرگ منجر به افزایش سرعت در اجرای سورسکد مربوطه میشود به علاوه اینکه آبجکتهایی از جنس تاپل را میتوان به عنوان مقادیر کلید در دیتا تایپهای دیکشنری مورد استفاده قرار داد چرا که مقادیر کلید در این نوع دیتا تایپ میباید به اصطلاح Immutable باشند و از همین روی آبجکتهایی از نوع دادۀ تاپل کاندیدای خوبی برای این سناریو هستند (جهت کسب اطلاعات بیشتر در رابطه با نوع دادۀ دیکشنری میتوانید به آموزش آشنایی با دیتا تایپ دیکشنری در زبان برنامهنویسی پایتون مراجعه نمایید.)
