جواب کوتاه: اگر مجموعه قرار است بعداً تغییر کند — آیتم اضافه یا حذف شود — list بگیرید. اگر یک رکورد ثابت است که معنایش با ترتیبش گره خورده (یک مختصات، یک ردیف پایگاهداده، یک RGB) tuple بگیرید. بقیهی تفاوتها همه از همین یک تصمیم میآیند.
تاپل تغییرناپذیر است، لیست نه
pythont = (1, 2, 3)
t[0] = 9
# TypeError: 'tuple' object does not support item assignment
l = [1, 2, 3]
l[0] = 9
print(l) # [9, 2, 3]
این تغییرناپذیری قرارداد نیست، اجراشونده است. اگر تابعی یک تاپل میگیرد، مطمئنید کسی داخلش را عوض نکرده — برخلاف لیست که هر تابعی میتواند در جا تغییرش بدهد.
فقط همین، تاپل را قابلهش میکند
pythond = {}
d[(1, 2)] = 'ok' # تاپل بهعنوان کلید دیکشنری، مجاز
d[[1, 2]] = 'fail'
# TypeError: unhashable type: 'list'
پایتون هر مقدار قابلتغییر را unhashable میداند، چون اگر بعد از قرار گرفتن در دیکشنری عوض شود، جای هشش دیگر درست نیست. برای همین tuple میتواند کلید دیکشنری یا عضو set باشد و list هرگز نمیتواند.
یک تفاوت کوچک در حافظه
pythonimport sys
sys.getsizeof((1, 2, 3, 4, 5)) # 88
sys.getsizeof([1, 2, 3, 4, 5]) # 104
تاپل چون تغییرناپذیر است، فضای اضافه برای رشد کنار نمیگذارد. روی یک آرایهی کوچک فرقش قابل چشمپوشی است، ولی وقتی میلیونها رکورد ثابت دارید (مثلاً خروجی یک کوئری) جمع میشود.
تلهی تاپل تکعضوی
pythonx = (1)
y = (1,)
type(x), type(y) # (<class 'int'>, <class 'tuple'>)
پرانتز بهتنهایی تاپل نمیسازد — کاما میسازد. (1) فقط یک عدد داخل پرانتز است. اگر یکبار این باگ را دیده باشید، دیگر یادتان نمیرود.
وقتی تاپل خوانا هم هست: namedtuple
pythonfrom collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
p.x # 1 — بهجای p[0] که معلوم نیست چیست
اگر یک تاپل دارید که فیلدهایش معنی مشخصی دارند (یک نقطه، یک رکورد کاربر)، namedtuple همان تغییرناپذیری را نگه میدارد ولی با اسم فیلد، نه با اندیس عددی که هر بار باید حدس بزنید کدام است.
جایی که تاپل بیسروصدا همهجا هست: مقدار بازگشتی چندتایی
pythondef min_max(nums):
return min(nums), max(nums)
lo, hi = min_max([4, 1, 9, 2])
print(lo, hi) # 1 9
وقتی یک تابع پایتون چند مقدار برمیگرداند، پشتصحنه دارد یک تاپل میسازد — return a, b همان return (a, b) است. برای همین است که میشود نتیجه را مستقیم unpack کرد؛ چیزی که با یک لیست هم جواب میداد، ولی نشان میدهد این خروجی یک رکورد ثابت دو-عضوی است، نه مجموعهای که قرار است بعداً بزرگ یا کوچک شود.
اگر مسیر یادگیری پایتون را از صفر میروید، دورهی پایتون این تصمیمها — کدام ساختار داده، کِی — را در تمرینهای واقعی تمرین میدهد، نه فقط تعریف.





نظرها
اولین نفری باشید که نظر میدهدسؤالتان را بپرسید یا تجربهتان را بنویسید — نویسندهی مطلب پاسخ میدهد.