آموزش

تفاوت list و tuple در پایتون؛ کِی کدام را انتخاب کنیم؟

هر دو مجموعه‌ای از مقادیر نگه می‌دارند، ولی یکی از این دو تغییرناپذیر است — و همین یک تفاوت، بقیه‌ی تفاوت‌ها را می‌سازد.

المان فتوحی
نویسنده
۴ دقیقه مطالعه۱ بازدید
اشتراک گذاری۱

جواب کوتاه: اگر مجموعه قرار است بعداً تغییر کند — آیتم اضافه یا حذف شود — 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 کرد؛ چیزی که با یک لیست هم جواب می‌داد، ولی نشان می‌دهد این خروجی یک رکورد ثابت دو-عضوی است، نه مجموعه‌ای که قرار است بعداً بزرگ یا کوچک شود.

اگر مسیر یادگیری پایتون را از صفر می‌روید، دوره‌ی پایتون این تصمیم‌ها — کدام ساختار داده، کِی — را در تمرین‌های واقعی تمرین می‌دهد، نه فقط تعریف.

المان فتوحی
نویسنده

نظرها

اولین نفری باشید که نظر می‌دهد
برای ثبت نظر وارد شوید

سؤالتان را بپرسید یا تجربه‌تان را بنویسید — نویسنده‌ی مطلب پاسخ می‌دهد.

مطالب مرتبط

از همین دسته
آموزش

چرا Rust به‌جای segfault، خطای کامپایل می‌دهد

در C یا ++C یک اشاره‌گر نامعتبر معمولاً ماه‌ها بعد، در پروداکشن، خودش را نشان می‌دهد. در Rust همان اشتباه، همان لحظه‌ی کامپایل متوقفت می‌کند.

تحریریه‌ی دینا کد۵ دقیقه
تفاوت list و tuple در پایتون — دینا کد