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

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

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

المان فتوحی
نویسنده
۴ دقیقه مطالعه۱ بازدید
اشتراک گذاری۱
فهرست مطالب
  1. ۱تاپل تغییرناپذیر است، لیست نه
  2. ۲فقط همین، تاپل را قابل‌هش می‌کند
  3. ۳یک تفاوت کوچک در حافظه
  4. ۴تله‌ی تاپل تک‌عضوی
  5. ۵وقتی تاپل خوانا هم هست: namedtuple
  6. ۶جایی که تاپل بی‌سروصدا همه‌جا هست: مقدار بازگشتی چندتایی

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

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

اگر می‌خواهید همین مفهوم‌ها را بدون نصب و همان لحظه محک بزنید، آموزش پایتون در مرورگر تمرین هر درس را با تصحیح خودکار آماده دارد.

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

نظرها

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

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

مطالب مرتبط

از همین دسته
دستور stash در گیت چیست و چه کاربردی دارد
آموزش

دستور stash در گیت چیست و چه کاربردی دارد

دستور stash در گیت تغییرات ثبت‌نشده شاخه کاری را موقتا کنار می‌گذارد تا بدون ثبت کامیت ناقص بتوانید روی وظایف فوری کار کنید.

تحریریه‌ی دینا کد۶ دقیقه
diff در گیت چیست و چه‌وقت استفاده می‌شود؟
آموزش

diff در گیت چیست و چه‌وقت استفاده می‌شود؟

git diff دو نسخه از کدها را کنار هم می‌گذارد و خط‌به‌خط نشان می‌دهد چه چیزی عوض شده. یک نگاه به diff قبل از هر add و commit کافی است

تحریریه‌ی دینا کد۷ دقیقه