در زبان پایتون، برای ذخیره مجموعهای از اطلاعات، دو ساختار داده بسیار پرکاربرد وجود دارد که در نگاه اول تقریباً یکسان بهنظر میرسند: لیستها که با [] ساخته میشوند و تاپلها که با () تعریف میشوند. این شباهت، یکی از اولین سوالات چالشبرانگیز، یعنی تفاوت لیست و تاپل در پایتون چیست؟ را برای هر برنامهنویس تازهکار ایجاد میکند. پاسخ این سؤال در تغییرپذیری (Mutability) است. به این معنا که لیستها تغییرپذیر (Mutable) هستند، یعنی شما میتوانید پساز ساخت، آیتمهای آنها را اضافه، حذف یا ویرایش کنید. درمقابل، تاپلها تغییرناپذیر (Immutable) هستند و پساز ساخته شدن، دیگر نمیتوان محتوای آنها را تغییر داد.
در این مقاله به مقایسه لیست و تاپل در پایتون میپردازیم، با مثالهای عملی نشان میدهیم که این تفاوت در عمل چه معنایی دارد و به شما کمک میکنیم تا برای همیشه بدانید که چه زمانی باید از لیست یا تاپل در پایتون استفاده کنید.
فهرست مطالب
مروری بر مفهوم لیست و تاپل
قبلاز اینکه وارد بیان تفاوت لیست و تاپل در پایتون شویم، بهتر است کمی توقف کنیم و ببینم هرکدام از این ساختارها چیستند؟ حتی اگر در پایتون حرفهای هستید، مرور آنها قبلاز ورود به بحث تفاوت لیست و تاپل میتواند مفید باشد. درضمن اگر بهتازگی وارد دنیای برنامهنویسی شدهاید، پیشنهاد میکنیم نگاهی به مقاله «پایتون چیست؟» بیندازید تا با مقدمات این زبان قدرتمند آشنا شوید.
مقاله تکمیلی: پایتون چیست؟ راهنمای شروع سریع برای تازهکارها
به زبان ساده، هم لیست و هم تاپل، محفظههایی برای نگهداری مجموعهای از دادهها بهصورت مرتب هستند. شما میتوانید انواع مختلفی از دادهها—اعداد، رشتهها یا حتی اشیاء دیگر را در آنها ذخیره کنید.
- لیست (List): یک مجموعه تغییرپذیر (Mutable) از دادهها است که با براکت [] تعریف میشود. تغییرپذیر بودن یعنی شما میتوانید پساز ساختن یک لیست، عناصر آن را اضافه، حذف یا ویرایش کنید.
- تاپل (Tuple): یک مجموعه تغییرناپذیر (Immutable) از دادهها است که با پرانتز () تعریف میشود. تغییرناپذیر بودن به این معنا است که پساز ایجاد یک تاپل، دیگر نمیتوانید محتویات آن را دستکاری کنید.
این تفاوت در «قابلیت تغییر» سنگ بنای اصلی فرق لیست و تاپل در پایتون است و تمام ویژگیهای دیگر آنها از همینجا نشئت میگیرد که در ادامه به تفصیل بررسی خواهیم کرد.
۵ تفاوت لیست و تاپل در پایتون

حالا به بخش جذاب ماجرا میرسیم. با اینکه لیست و تاپل در ظاهر شبیه هستند، اما در باطن تفاوتهای عمیقی دارند که شخصیت و کاربرد هرکدام را مشخص میکند. درک تفاوت لیست و تاپل در پایتون به شما کمک میکند تا کدی بهینهتر و ایمنتر بنویسید.
مروری سریع بر فرق 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 و 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)
قانون طلایی این است: اگر مجموعه دادههای شما پویا است و در طول اجرای برنامه نیاز به تغییر دارد از لیست استفاده کنید. لیستها برای دادههایی طراحی شدهاند که زنده هستند و وضعیتشان عوض میشود. اگر نیاز به افزودن، حذف یا ویرایش عناصر دارید، لیست انتخاب بیچونوچرای شماست.
مثالهای استفاده از لیست:
- سبد خرید در یک فروشگاه آنلاین: کاربران مدام محصولاتی را اضافه یا حذف میکنند.
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 سرور، نام کاربری یا پسورد دیتابیس که در طول اجرای برنامه ثابت باقی میمانند.
یک چالش رایج در انتخاب لیست و تاپل
شما اکنون تفاوت تئوریک لیست و تاپل در پایتون را میدانید. اما آیا میدانستید که در برخی موارد، این انتخاب فقط یک ترجیح نیست، بلکه یک اجبار فنی است؟
یک مثال کلاسیک: شما نمیتوانید از یک لیست به عنوان کلید (Key) در یک دیکشنری (Dictionary) استفاده کنید، اما میتوانید از یک تاپل برای این کار بهره ببرید. چرا؟ چون کلیدهای دیکشنری باید تغییرناپذیر (Immutable) و قابل هش (Hashable) باشند. تلاش برای استفاده از یک لیست بهعنوان کلید، با خطای TypeError: unhashable type: ‘list’ مواجه خواهد شد.
این چالش کوچک به بهترین شکل فلسفه وجودی تاپل را آشکار میکند و نشان میدهد که چرا تغییرناپذیری» فقط یک ویژگی ساده نیست، بلکه یک اصل مهم در طراحی ساختارهای داده پیچیده است.
ابزار مناسب برای درک عمیقتر
بهترین راه برای درک عمیق این مفاهیم، آزمایش کردن و دیدن خطاها با چشمان خودتان است و بهترین محیط موجود نیز که قابلیت تعاملی بالایی نیز دارد ژوپیتر لب (JupyterLab) است. ابر فردوسی سرور ژوپیتر لب ابری خود را بهصورت آماده و بهینهسازیشده در اختیار شما قرار می دهد. شما میتوانید صرفاً با چند کلیک و بدون نصب چیزی وارد ژوپیتر لب خود شوید و با تست چالشها، مفاهیم پایتون را به صورت عملی و عمیق بیاموزید.
اگر میخواهید درباره این ابزار قدرتمند، اطلاعات دقیقتری بهدست بیاورید به مقاله جامع زیر مراجعه کنید.
مزایای سرویس ژوپیتر لب ابر فردوسی:
- در کمتر از یک دقیقه، یک محیط کامل و آمادهبهکار در اختیار شماست.
- همه پکیجها ازقبل نصب شدهاست و شما نیاز به نصب هیچچیزی ندارید.
- برای تست سریع کدهایی مانند مثالهایی که در بیان تفاوت لیست و تاپل در پایتون گفتیم، بهترین ابزار ممکن است.
- ابزاری که متخصصان داده و محققان درسراسر جهان از آن استفاده میکنند.
- امکان تغییر منابع دارید و با بزرگشدن پروژه میتوانید با چند کلیک منابع سختافزاری خود را افزایش دهید.
- در همان ابتدای ثبتنام ۱۰۰ هزارتومان اعتبار رایگان برای تست امکانات به حساب شما شارژ میشود.
جمعبندی
تفاوت لیست و تاپل در پایتون به قصد و نیت شما بستگی دارد. لیستها برای مجموعههایی هستند که میدانیم در طول برنامه قرار است تغییر کنند (مانند لیست کاربران یک سایت) و تاپلها برای دادههایی هستند که باید بهعنوان یک مجموعه ثابت و دستنخورده باقی بمانند (مانند مختصات یک نقطه روی نقشه).
یک قانون سرانگشتی خوب: اگر شک دارید، با تاپل شروع کنید. تاپلها امنتر و کمی بهینهتر هستند. اگر در ادامه مسیر متوجه شدید که نیاز به تغییر در مجموعه خود دارید، آنگاه به سادگی میتوانید آن را به یک لیست تبدیل کنید. این رویکرد، کد شما را خواناتر و کمتر مستعد خطا میکند.
شما در کدام موقعیت جالب با انتخاب بین لیست و تاپل مواجه شدهاید؟ تجربه خود را در بخش نظرات با ما در میان بگذارید.
سؤالات متداول
فرق لیست و تاپل در پایتون چیست؟
اصلیترین تفاوت در «قابلیت تغییر» است. لیستها تغییرپذیر (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) باشند.
آیا تاپلها همیشه بهتر از لیستها هستند؟
خیر. این یک تصور اشتباه است. آنها ابزارهای متفاوتی برای کارهای متفاوت هستند. اگر وظیفه شما ایجاب میکند که دادهها را در طول برنامه تغییر دهید (مانند یک سبد خرید)، لیست نه تنها بهتر، بلکه انتخاب صحیح است. بهترین ابزار، ابزاری است که با نیاز شما مطابقت داشته باشد.

