ساختار داده تاپل (Tuple) در پایتون
ساختار داده تاپل (Tuple) در پایتون
ساختار داده تاپل در پایتون
در پایتون، هنگامی که نیاز به ذخیره مجموعهای از دادهها به صورت مرتب و غیرقابل تغییر باشد، از ساختار داده تاپل (Tuple) استفاده میشود. تاپلها شباهت زیادی به لیستها دارند، اما با یک تفاوت بنیادین: تغییرناپذیری (Immutability).
تاپل چیست؟
تاپل یک دنباله مرتب (Ordered)، تغییرناپذیر (Immutable) و با قابلیت پذیرش مقادیر تکراری است.
- تغییرناپذیری (Immutable): پس از ساخت تاپل، نمیتوان عضوی به آن اضافه کرد، از آن حذف نمود یا مقدار هیچیک از اعضا را تغییر داد.
- سرعت و مصرف حافظه کمتر: به دلیل غیرقابل تغییر بودن، تاپلها نسبت به لیستها سبکتر بوده و سرعت پردازش بالاتری دارند.
- ناهمگن: می توان انواع داده های مختلف را به عنوان المان بپذیرد
- مرتب: المان ها با اندیس فراخوانی می شوند.
- کاربردها:
- محافظت از دادههای حساس در برابر تغییر ناخواسته (Write-Protecting Data).
- استفاده به عنوان کلید در دیکشنریها (چون کلید دیکشنری باید Immutable باشد).
- بازگرداندن چندین مقدار خروجی همزمان از یک تابع (Return Multiple Values).
- نگهداری مقادیر ثابت مهندسی و مختصات جغرافیایی (مانند طول و عرض جغرافیایی یا ابعاد تصویر).
نحوه ساخت تاپل
تاپل با پرانتز () یا تابع سازنده tuple() ساخته میشود. همچنین تعریف مقادیر با کاما بدون پرانتز نیز به عنوان تاپل شناخته میشود:
# تاپل خالی
empty_tuple = ()
# تاپل تکعضوی (گذاشتن کاما الزامی است)
single_item = ("data",)
# تاپل همگن عددی
coordinates = (35.6892, 51.3890)
تاپل میتواند انواع مختلف نوع داده (عدد، رشته، بولین و حتی اشیای تغییرپذیر مانند لیست) را در خود نگهداری کند:
mixed_tuple = (
101, # عدد صحیح
"ECG_Signal", # رشته
True, # بولین
3.1415, # عدد اعشاری
[10, 20, 30], # لیست
{"sampling_rate": 250} # دیکشنری
)
اندیسگذاری (Indexing) و برشدادن (Slicing)
قوانین دسترسی به اعضای تاپل دقیقاً مشابه لیست و رشته است:
- اندیس مثبت: از چپ به راست با شروع از
0 - اندیس منفی: از راست به چپ با شروع از
1- - برشدادن (Slicing): با ساختار
tuple[start:stop:step]
channels = ("Lead I", "Lead II", "Lead III", "aVR", "aVL", "aVF")
first_lead = channels[0] # خروجی: 'Lead I'
last_lead = channels[-1] # خروجی: 'aVF'
sub_channels = channels[1:4] # خروجی: ('Lead II', 'Lead III', 'aVR')
متدهای تاپل
به دلیل تغییرناپذیر بودن تاپل، متدهایی برای افزودن، حذف یا مرتبسازی در آن وجود ندارد و تنها دو متد جستوجو و شمارش برای آن تعریف شده است:
متد count(x)
- توضیح: تعداد دفعات تکرار مقدار
xرا در طول تاپل محاسبه میکند. - صورت مسئله: میخواهیم بررسی کنیم که وضعیت
"Normal"چند بار در نتیجه ارزیابیهای ثبتشده تکرار شده است.
diagnoses = ("Normal", "MI", "Normal", "STTC", "Normal")
normal_count = diagnoses.count("Normal")
print("تعداد وضعیت عادی:", normal_count) # خروجی: 3
متد index(x)
- توضیح: اندیس (موقعیت) اولین حضور مقدار
xرا در تاپل بازمیگرداند (در صورت نبود مقدار، خطایValueErrorمیدهد). - صورت مسئله: میخواهیم موقعیت نام کانال
"Lead III"را در لیست ثابت کانالهای اندازهگیری به دست آوریم.
leads = ("Lead I", "Lead II", "Lead III", "V1", "V2")
lead_pos = leads.index("Lead III")
print("موقعیت Lead III:", lead_pos) # خروجی: 2
محدودیت تاپلها
تاپلها ساختار داده محاسباتی نیستند و از عملیات ریاضی مستقیم روی دادههای عددی پشتیبانی نمیکنند:
- عملگر
+دو تاپل را با هم ادغام (الحاق) میکند و اعضای نظیربهنظیر را جمع نمیزند. - عملگر
*تاپل را تکرار میکند و اعضا را در عدد ضرب نمیکند.
tuple_a = (1, 2, 3)
tuple_b = (4, 5, 6)
print(tuple_a + tuple_b) # خروجی: (1, 2, 3, 4, 5, 6)
print(tuple_a * 2) # خروجی: (1, 2, 3, 1, 2, 3)
نکته: برای انجام محاسبات ماتریسی و برداری سریع، از آرایههای کتابخانه NumPy استفاده میشود.
سه مثال کاربردی
مثال ۱: بازگرداندن چندین خروجی از یک تابع
محاسبه و بازگرداندن همزمان (Multiple Returns) کمترین، بیشترین و میانگین دادههای یک سیگنال در قالب تاپل:
def analyze_signal(samples):
min_val = min(samples)
max_val = max(samples)
avg_val = sum(samples) / len(samples)
return min_val, max_val, avg_val # خروجی به صورت تاپل برگردانده میشود
data = [0.12, 0.85, 0.43, 1.21, 0.05]
minimum, maximum, average = analyze_signal(data)
print(f"کمترین: {minimum}, بیشترین: {maximum}, میانگین: {average:.2f}")
مثال ۲: تاپلگشایی و ثبت مشخصات ثابت
استخراج سریع متغیرها از رکوردهای ثابت سیستمی (Tuple Unpacking):
# نگهداری تنظیمات سختافزاری: (پورت, نرخ نمونهبرداری, پروتکل)
device_config = (8080, 500, "TCP")
port, sampling_rate, protocol = device_config
print(f"پورت: {port}")
print(f"نرخ نمونهبرداری: {sampling_rate} Hz")
print(f"پروتکل: {protocol}")
مثال ۳: استفاده از تاپل به عنوان کلید دیکشنری
ثبت موقعیت سنسورها در یک شبکه مختصات دوبعدی (x, y) که به دلیل تغییرناپذیری تاپل امکانپذیر است:
# مختصات سنسورها (X, Y) به عنوان کلید دیکشنری
sensor_network = {
(0, 0): "Main Gateway",
(10, 25): "Sensor A",
(30, 45): "Sensor B"
}
target_coord = (10, 25)
print(f"نام سنسور در مختصات {target_coord}:", sensor_network[target_coord])
