یک برنامهنویس پایتون باید دقیقاً بداند چه زمانی از کدام ساختار داده استفاده کند. دو مورد از پرکاربردترین و بنیادیترین ساختارهای داده در این زبان، لیست (List) و تاپل (Tuple) هستند. شاید در نگاه اول این دو بسیار شبیه بهنظر برسند، اما تفاوتهای کلیدی و مهمی دارند که درک آنها میتواند تأثیر مستقیمی بر کارایی، سرعت و خوانایی کد شما داشته باشد.
هدف این مقاله دقیقاً همین است: یک راهنمای کاربردی و ساده برای درک کامل تفاوت لیست و تاپل در پایتون تا شما بتوانید با خیال راحت، بهترین ابزاری که با پروژهتان تناسب دارد را انتخاب کنید.
فهرست مطالب
لیست و تاپل چیستند؟ یک معرفی کوتاه
قبلاز اینکه وارد بیان تفاوت لیست و تاپل در پایتون شویم، بهتر است کمی توقف کنیم و ببینم هرکدام از این ساختارها چیستند؟ حتی اگر در پایتون حرفهای هستید، مرور آنها قبلاز ورود به بحث تفاوت لیست و تاپل میتواند مفید باشد. درضمن اگر بهتازگی وارد دنیای برنامهنویسی شدهاید، پیشنهاد میکنیم نگاهی به مقاله «پایتون چیست؟» بیندازید تا با مقدمات این زبان قدرتمند آشنا شوید.
به زبان ساده، هم لیست و هم تاپل، محفظههایی برای نگهداری مجموعهای از دادهها بهصورت مرتب هستند. شما میتوانید انواع مختلفی از دادهها—اعداد، رشتهها یا حتی اشیاء دیگر را در آنها ذخیره کنید.
- لیست (List): یک مجموعه تغییرپذیر (Mutable) از دادهها است که با براکت [] تعریف میشود. تغییرپذیر بودن یعنی شما میتوانید پساز ساختن یک لیست، عناصر آن را اضافه، حذف یا ویرایش کنید.
- تاپل (Tuple): یک مجموعه تغییرناپذیر (Immutable) از دادهها است که با پرانتز () تعریف میشود. تغییرناپذیر بودن به این معنا است که پساز ایجاد یک تاپل، دیگر نمیتوانید محتویات آن را دستکاری کنید.
این تفاوت در «قابلیت تغییر» سنگ بنای اصلی فرق لیست و تاپل در پایتون است و تمام ویژگیهای دیگر آنها از همینجا نشئت میگیرد که در ادامه به تفصیل بررسی خواهیم کرد.
لیست (List) و تاپل (Tuple) در یک نگاه: مرور شباهتها
پیشاز آنکه روی تفاوت لیست و تاپل در پایتون تمرکز کنیم، بهتر است ببینیم این دو ساختار داده در چه مواردی شبیه به هم عمل میکنند. درک این شباهتها به شما کمک میکند تا منطق کلی حاکم بر هر دو را بهتر بفهمید. در عمل، لیست و تاپل در پایتون در دو حوزه کلیدی کاملاً یکسان رفتار میکنند.
۱- شباهت در نحوه تعریف و ساختار (Syntax)
اولین و واضحترین شباهت در مقایسه لیست و تاپل در پایتون، ظاهر و ساختار کلی آنها است. هر دو برای نگهداری مجموعهای از آیتمها طراحی شدهاند و ترتیب عناصر را حفظ میکنند (Ordered). این یعنی اولین عنصری که وارد میکنید همیشه در خانه شماره صفر باقی میماند، مگر اینکه خودتان آن را تغییر دهید (که البته این کار فقط در لیستها ممکن است).
تنها تفاوت ظاهری در کاراکترهایی است که برای تعریفشان استفاده میشود:
- لیستها با براکت [] ساخته میشوند.
- تاپلها با پرانتز () ساخته میشوند.
# تعریف یک لیست با دادههای مختلف
my_list = [1, "cloud", 3.14]
# تعریف یک تاپل با همان دادهها
my_tuple = (1, "cloud", 3.14)
print(my_list)
# خروجی: [1, 'cloud', 3.14]
print(my_tuple)
# خروجی: (1, 'cloud', 3.14)
همانطور که میبینید، هر دو میتوانند دادههایی از انواع مختلف (عدد، رشته و…) را در خود جای دهند.
۲- شباهت در دسترسی و بُرشزدن عناصر (Indexing & Slicing)
از آنجاییکه هر دو ساختار، دادهها را بهصورت مرتب ذخیره میکنند، فرایند دسترسی به عناصر در آنها کاملاً یکسان است. شما میتوانید با استفاده از شماره ایندکس (که از صفر شروع میشود) به یک عنصر خاص دسترسی پیدا کنید یا با «بُرش زدن» (Slicing)، بخشی از آنها را استخراج کنید.
در ادامه این شباهت را با یک مثال کد بررسی میکنیم:
# یک لیست و یک تاپل برای نمونه
servers = ["web-server-01", "db-server", "cache-server", "monitoring"]
ip_addresses = ("192.168.1.10", "192.168.1.15", "10.0.0.5")
# --- دسترسی به اولین عنصر (ایندکس صفر) ---
print(f"First Server: {servers[0]}") # خروجی: First Server: web-server-01
print(f"First IP: {ip_addresses[0]}") # خروجی: First IP: 192.168.1.10
# --- بُرش زدن و استخراج دو عنصر اول ---
print(f"First two servers: {servers[0:2]}") # خروجی: First two servers: ['web-server-01', 'db-server']
print(f"First two IPs: {ip_addresses[0:2]}") # خروجی: First two IPs: ('192.168.1.10', '192.168.1.15')
همانطور که میبینید، سینتکس دسترسی و برش زدن برای هر دو دقیقاً یکسان است. تا اینجا، لیست یا تاپل مانند دوقلوهای همسان بهنظر میرسند. اما در بخش بعدی، وارد تفاوت List و Tuple در پایتون میشویم. اینجا است که شخصیت واقعی هرکدام آشکار میشود.
مقایسه لیست و تاپل: ۵ تفاوت کلیدی که باید بدانید
حالا به بخش جذاب ماجرا میرسیم. با اینکه لیست و تاپل در ظاهر شبیه هستند، اما در باطن تفاوتهای عمیقی دارند که شخصیت و کاربرد هرکدام را مشخص میکند. درک تفاوت لیست و تاپل در پایتون به شما کمک میکند تا کدی بهینهتر و ایمنتر بنویسید.
مروری سریع بر فرق List و Tuple در پایتون:
ویژگی | لیست (List) | تاپل (Tuple) |
---|---|---|
قابلیت تغییر | تغییرپذیر (Mutable) | تغییرناپذیر (Immutable) |
سرعت | معمولی | سریعتر |
حافظه | مصرف بیشتر | مصرف بهینهتر |
متدها | متنوع (افزودن، حذف، مرتبسازی) | محدود (شمارش، جستجو) |
کلید دیکشنری | نمیتواند باشد | میتواند باشد |
در ادامه، هر یک از این موارد را با مثالهای عملی باز میکنیم.
۱. قابلیت تغییر (Mutable vs. Immutable): مهمترین تفاوت لیست و تاپل در پایتون
قابلیت تغییر را میتوان اساسیترین تفاوت لیست و تاپل در پایتون بهحساب آورد. لیستها تغییرپذیر (Mutable) هستند: یعنی شما میتوانید پساز ساختن یک لیست، محتوای آن را کم، زیاد یا ویرایش کنید.
# یک لیست از سرویسهای فعال
active_services = ["nginx", "database", "redis"]
print(f"Before change: {active_services}")
# ویرایش یک عنصر
active_services[1] = "postgresql"
# اضافه کردن یک عنصر جدید
active_services.append("logging")
print(f"After change: {active_services}")
# خروجی:
# Before change: ['nginx', 'database', 'redis']
# After change: ['nginx', 'postgresql', 'logging']
تاپلها تغییرناپذیر (Immutable) هستند: پساز تعریف یک تاپل، دیگر نمیتوانید هیچکدام از عناصر آن را تغییر دهید. این ویژگی، ایمنی و یکپارچگی دادههای شما را تضمین میکند. تلاش برای تغییر یک تاپل منجر به خطای TypeError میشود.
# مختصات یک نقطه جغرافیایی (دادهای که نباید تغییر کند)
coordinates = (35.6892, 51.3890)
print(f"Coordinates: {coordinates}")
# تلاش برای تغییر مقدار (این کد خطا میدهد!)
try:
coordinates[0] = 32.6539
except TypeError as e:
print(f"Error: {e}")
# خروجی:
# Coordinates: (35.6892, 51.3890)
# Error: 'tuple' object does not support item assignment
۲. عملکرد و سرعت اجرا (Performance)
بهطور کلی تاپلها سریعتر از لیستها هستند. دلیل این امر به ساختار ثابت آنها برمیگردد. از آنجاییکه پایتون میداند یک تاپل هرگز تغییر اندازه نخواهد داد، میتواند بهینهسازیهایی در سطح حافظه و پردازش روی آن انجام دهد. در مقابل، لیستها بهدلیل ماهیت پویای خود به کمی سربار (overhead) برای مدیریت تغییرات احتمالی نیاز دارند.
این تفاوت سرعت در مجموعههای داده کوچک تقریباً نامحسوس است، اما هنگام کار با میلیونها داده میتواند تأثیر قابلتوجهی داشته باشد.
۳. تفاوت در مصرف حافظه (Memory Usage)
سومین تفاوت لیست و تاپل در پایتون به مصرف حافظه آنها برمیگردد. تاپلها حافظه کمتری مصرف میکنند. این موضوع نیز مستقیماً به تفاوت اول برمیگردد. پایتون برای لیستها مقداری حافظه اضافی تخصیص میدهد تا درصورت افزودن عناصر جدید، فرایند رشد لیست سریعتر انجام شود. اما برای تاپلها، حافظه دقیقاً به اندازه عناصر موجود تخصیص داده میشود.
میتوانیم این تفاوت لیست و تاپل را با ماژول sys بررسی کنیم:
import sys
my_list = [1, 2, 3, 4, 5]
my_tuple = (1, 2, 3, 4, 5)
print(f"List size: {sys.getsizeof(my_list)} bytes")
print(f"Tuple size: {sys.getsizeof(my_tuple)} bytes")
# خروجی احتمالی:
# List size: 104 bytes
# Tuple size: 80 bytes
۴. متدهای در دسترس (Available Methods)
از آنجاییکه لیستها برای تغییر ساخته شدهاند، مجموعهای غنی از متدها مانند append(), extend(), insert(), remove(), pop() و sort() را برای دستکاری دادهها ارائه میدهند. در مقابل، تاپلها چون تغییرناپذیرند، تنها دو متد اصلی دارند که محتوای آن را تغییر نمیدهند:
- count(): تعداد تکرار یک عنصر را برمیگرداند.
- index(): شماره ایندکس اولین wystąpienie یک عنصر را پیدا میکند.
۵. کاربرد بهعنوان کلید دیکشنری
و آخرین تفاوت لیست و تاپل در پایتون به این موضوع برمیگردد که در پایتون، کلیدهای یک دیکشنری (Dictionary) باید حتماً از نوع دادهِ تغییرناپذیر (Immutable) باشند. این یک قانون است؛ زیرا اگر کلید تغییر کند، پایتون دیگر نمیتواند مقدار متناظر با آن را پیدا کند. به همین دلیل:
- میتوانید از تاپل بهعنوان کلید دیکشنری استفاده کنید.
- نمیتوانید از لیست بهعنوان کلید دیکشنری استفاده کنید.
# تعریف یک دیکشنری برای ذخیره پایتخت کشورها با کلید تاپل (کشور، قاره)
capitals = {}
key_iran = ("Iran", "Asia")
capitals[key_iran] = "Tehran"
print(capitals)
# خروجی: {('Iran', 'Asia'): 'Tehran'}
# تلاش برای استفاده از لیست بهعنوان کلید (این کد خطا میدهد!)
try:
key_germany = ["Germany", "Europe"]
capitals[key_germany] = "Berlin"
except TypeError as e:
print(f"Error: {e}")
# خروجی:
# Error: unhashable type: 'list'
این ویژگی تاپلها را برای سناریوهایی که نیاز به یک شناسه ترکیبی و ثابت دارید مناسب میسازد.
کی از لیست استفاده کنیم و کی از تاپل؟ (راهنمای انتخاب)
اکنون که با جزئیات فنی و تفاوت لیست و تاپل در پایتون آشنا شدیم به مهمترین سؤال میرسیم: «بالأخره از کدامیک باید استفاده کنم؟». پاسخ این سؤال به هدف شما بستگی دارد. انتخاب بین لیست یا تاپل در پایتون، تصمیمی است که باید براساس ماهیت دادههایتان آن را اتخاذ کنید. در ادامه، سناریوهای عملی هرکدام را بررسی میکنیم.
سناریوهای ایدئال برای استفاده از لیست (List)
قانون طلایی این است: اگر مجموعه دادههای شما پویا است و در طول اجرای برنامه نیاز به تغییر دارد از لیست استفاده کنید. لیستها برای دادههایی طراحی شدهاند که زنده هستند و وضعیتشان عوض میشود. اگر نیاز به افزودن، حذف یا ویرایش عناصر دارید، لیست انتخاب بیچونوچرای شماست.
مثالهای استفاده از لیست:
- سبد خرید در یک فروشگاه آنلاین: کاربران مدام محصولاتی را اضافه یا حذف میکنند.
shopping_cart = ["کتاب پایتون", "قهوه"]
shopping_cart.append("ماوس بیسیم") # افزودن محصول
shopping_cart.remove("قهوه") # حذف محصول
- لیست وظایف (To-Do List): لیستی که در طول روز وظایفی به آن اضافه یا از آن کم میشود.
- دادههای ورودی برای فیلتر یا مرتبسازی: وقتی دادهها را از یک فایل میخوانید و میخواهید آنها را درجا (in-place) مرتب یا پاکسازی کنید.
سناریوهای ایدئال برای استفاده از تاپل (Tuple)
قانون طلایی اینجا نیز ساده است: اگر دادههای شما ثابت هستند و نباید تحت هیچ شرایطی تغییر کنند، از تاپل استفاده کنید. استفاده از تاپل نوعی قرارداد با خودتان و سایر برنامهنویسان است که نشان میدهد این دادهها برای «فقط خواندن» (Read-only) هستند. این کار باعث افزایش ایمنی و یکپارچگی دادهها میشود و از تغییرات ناخواسته جلوگیری میکند.
مثالهای استفاده از تاپل:
- مختصات جغرافیایی یا رنگهای RGB: اینها مقادیر ثابتی هستند. یک نقطه روی نقشه همیشه همان نقطه است.
TEHRAN_COORDINATES = (35.6892, 51.3890)
PRIMARY_RED_COLOR = (255, 0, 0)
- بازگرداندن مقادیر چندگانه از یک تابع: وقتی یک تابع قرار است چندین مقدار ثابت را برگرداند، تاپل یک راه زیبا و بهینه برای این کار است.
def get_user_info(user_id):
# (اطلاعات از دیتابیس خوانده میشود)
username = "ferdowsi_cloud"
is_active = True
return (username, is_active) # بازگرداندن نام کاربری و وضعیت در یک تاپل
- تنظیمات یک برنامه: اطلاعاتی مانند آدرس IP سرور، نام کاربری یا پسورد دیتابیس که در طول اجرای برنامه ثابت باقی میمانند.
کدنویسی بدون دردسر: لیست و تاپل را در ژوپیتر لب ابری تمرین کنید
تئوری و دانش یک طرف ماجراست؛ تجربه و تمرین عملی طرف دیگر. حالا که تفاوت لیست و تاپل در پایتون را به خوبی میدانید، بهترین کار این است که خودتان دستبهکد شوید. اما بیایید صادق باشیم: فرایند آمادهسازی محیط کدنویسی روی سیستم میتواند خستهکنندهتر از خودِ یادگیری باشد.
درگیری با نسخههای مختلف پایتون، مدیریت کتابخانهها، خطاهای بیپایان هنگام نصب و این سؤال همیشگی که «چرا این کد روی سیستم من کار نمیکند؟». اگر با این چالشها آشنا هستید (که در مقالههای «راهنمای نصب پایتون» و «ماژولهای محبوب پایتون» به آنها پرداختهایم)، احتمالاً زمان زیادی را از دست دادهاید که میتوانست صرف یادگیری مفاهیم اصلی شود.
واقعیت این است که در دنیای حرفهای امروز، دیگر کسی زمان خود را برای راهاندازیهای تکراری هدر نمیدهد و برنامهنویسان زیادی به زیرساختهای ابری و یکپارچه مانند ژوپیتر لب ابری تمایل پیدا کردهاند.
چرا ژوپیتر لب برای تمرین پایتون بینظیر است؟
سرور ژوپیتر لب فردوسی دقیقاً برای حل همین مشکل طراحی شدهاست. یک محیط کدنویسی حرفهای و آماده که در آن نیازی به نصب هیچچیز ندارید.
- دسترسی آنی: در کمتر از یک دقیقه، یک محیط پایتون کامل و آمادهبهکار در اختیار شماست.
- بدون دغدغه نصب: بهجای جنگیدن با پکیج منیجرها، فقط کدنویسی کنید.
- محیط تعاملی: برای تست سریع کدهایی مانند مثالهایی که در بیان تفاوت لیست و تاپل در پایتون گفتیم، بهترین ابزار ممکن است.
- استاندارد جهانی: ابزاری که متخصصان داده و محققان در سراسر جهان از آن استفاده میکنند.
وقت آن رسیده که هوشمندانه کار کنید. تمام مثالهای این مقاله را همین حالا در یک محیط حرفهای و بدون دردسر اجرا کنید. برای شروع، کافی است نگاهی به ژوپیتر لب فردوسی بیندازید و اگر میخواهید بیشتر با این ابزار قدرتمند آشنا شوید، مقاله ژوپیتر لب چیست؟ را از دست ندهید.
تفاوت لیست و تاپل در پایتون: سخن پایانی ابر فردوسی
اگر بخواهیم سؤال «تفاوت لیست و تاپل در پایتون چیست؟» را در یک کلمه کلیدی خلاصه کنیم، باید بگوییم: تغییرپذیری (Mutability).
- اگر به مجموعهای از دادهها نیاز دارید که در طول زمان تغییر میکنند، لیست ابزار شما است.
- اگر با دادههایی سروکار دارید که باید ثابت و دستنخورده باقی بمانند، تاپل انتخاب ایمن و بهینه شما خواهد بود.
درک این تفاوت ساده، شما را یک قدم به نوشتن کدهای پایتونی تمیزتر، کارآمدتر و حرفهایتر نزدیکتر میکند. حالا نوبت شما است که این دانش را به کار بگیرید و پروژههای بهتری بسازید.
سؤالات متداول درباره « تفاوت لیست و تاپل در پایتون»
فرق لیست و تاپل در پایتون چیست؟
اصلیترین تفاوت در «قابلیت تغییر» است. لیستها تغییرپذیر (Mutable) هستند و میتوانید عناصر آنها را پساز ساخت، اضافه، حذف یا ویرایش کنید. اما تاپلها تغییرناپذیر (Immutable) هستند و پساز ساخته شدن، محتوای آنها ثابت باقی میماند.
آیا میتوان لیست و تاپل را به یکدیگر تبدیل کرد؟
بله. این کار به سادگی با استفاده از توابع داخلی پایتون انجام میشود. برای تبدیل یک تاپل به لیست از تابع list() و برای تبدیل یک لیست به تاپل از تابع tuple() استفاده کنید.
my_tuple = (1, 2, 3)
my_list = list(my_tuple) # تبدیل تاپل به لیست
print(my_list) # خروجی: [1, 2, 3]
new_tuple = tuple(my_list) # تبدیل لیست به تاپل
print(new_tuple) # خروجی: (1, 2, 3)
چرا با خطای ‘tuple’ object does not support item assignment مواجه میشوم؟
این خطا یکی از رایجترین موارد در کار با تاپلها است و زمانی رخ میدهد که شما تلاش میکنید یک عنصر از یک تاپل را مستقیماً تغییر دهید. از آنجایی که تاپلها تغییرناپذیرند، پایتون با این خطا جلوی شما را میگیرد. برای اطلاعات بیشتر درباره خطاهای رایج، مقاله «رفع سریع ۱۰ ارور پرتکرار در پایتون» را مطالعه کنید.
کدام یک سریعتر است، لیست یا تاپل؟
بهطور کلی، تاپلها سریعتر هستند. دلیلش هم این است که ساختار ثابت و تغییرناپذیری دارند و پایتون میتواند آنها را بهینهتر مدیریت و پردازش کند. این تفاوت در مجموعه دادههای بسیار بزرگ محسوستر است.
در تحلیل داده با Pandas، کدام یک کاربرد بیشتری دارد؟
هر دو کاربرد دارند، اما در جایگاههای متفاوت. ستونهای دیتافریمهای پانداس (Pandas Series) خودشان تغییرپذیر هستند و به لیستها شباهت دارند. اما تاپلها اغلب برای ساخت ایندکسهای چندسطحی (MultiIndex) استفاده میشوند؛ زیرا کلیدهای ایندکس باید تغییرناپذیر (hashable) باشند.
آیا تاپلها همیشه بهتر از لیستها هستند؟
خیر. این یک تصور اشتباه است. آنها ابزارهای متفاوتی برای کارهای متفاوت هستند. اگر وظیفه شما ایجاب میکند که دادهها را در طول برنامه تغییر دهید (مانند یک سبد خرید)، لیست نه تنها بهتر، بلکه انتخاب صحیح است. بهترین ابزار، ابزاری است که با نیاز شما مطابقت داشته باشد.