Table of Contents
مقایسه و انتخاب ساختار داده
در فصل «مجموعههای داده» با چهار ساختار اصلی آشنا شدید:
- لیستها (
list) - تاپلها (
tuple) - دیکشنریها (
dict) - مجموعهها (
set)
در این بخش، تمرکز ما روی این است که در هر مسئله کدامیک را انتخاب کنیم و چرا؛ نه روی نحو (syntax) و جزئیات که قبلاً دیدهاید.
چند سؤال کلیدی برای انتخاب ساختار داده
پیش از انتخاب ساختار، این سؤالها را از خود بپرسید:
- آیا ترتیب (order) عناصر برای من مهم است؟
- بله → معمولاً
listیاtuple - نه → میتوان
setیاdictرا هم در نظر گرفت - آیا دادهها قرار است بعداً تغییر کنند؟ (افزودن، حذف، ویرایش)
- بله → ساختار قابلتغییر (mutable) مثل
list,dict,set - نه → ساختار ثابت مثل
tuple(برای امنیت و جلوگیری از تغییر ناخواسته) - چگونه قرار است به دادهها دسترسی پیدا کنم؟
- با شمارهٔ موقعیت (۰، ۱، ۲، …) →
listیاtuple - با یک کلید معنادار (مثل
name,age,id) →dict - بیشتر میخواهم بدانم «آیا این عضو هست یا نه؟» →
set(و تا حدیdict) - آیا عناصر میتوانند تکراری باشند؟
- بله →
list,tuple,dict(کلیدها تکراری نیستند، ولی مقدارها میتوانند باشند) - نه →
set(بهصورت خودکار تکراریها را حذف میکند)
با همین چهار سؤال، در اکثر موقعیتهای ساده میتوانید ساختار مناسب را انتخاب کنید.
لیست (`list`) را چه زمانی انتخاب کنیم؟
ویژگی مهم: قابلتغییر، مرتب، پشتیبانی از عناصر تکراری، دسترسی با اندیس.
لیست معمولاً اولین انتخاب برای دادههای «چندتایی» است؛ مثل:
- فهرست دانشآموزان یک کلاس
- قیمتهای روزانهٔ یک سهم
- شمارههای یک قرعهکشی
مناسب است وقتی:
- ترتیب وارد کردن دادهها مهم است (مثلاً ترتیب ثبت سفارشها).
- باید بتوانید عناصر را اضافه یا حذف کنید.
- میخواهید روی همهٔ عناصر به ترتیب حلقه بزنید (
for x in my_list:). - میخواهید با اندیس کار کنید:
my_list[0],my_list[-1].
مثالهای رایج استفاده از لیست:
- صف انتظار مشتریها
- فهرست کارها (To-Do List)
- تاریخچهٔ دستورات کاربر در یک برنامه
تاپل (`tuple`) را چه زمانی انتخاب کنیم؟
ویژگی مهم: مرتب، اما غیرقابلتغییر (immutable).
تاپل را زمانی استفاده کنید که:
- میخواهید چند مقدار را بهصورت یک واحد ثابت نگه دارید.
- این دادهها ماهیت «رکورد» دارند و قرار نیست بعداً تغییر کنند.
نمونهٔ متعارف:
- مختصات یک نقطه روی صفحه:
(x, y) - تاریخ تولد:
(سال، ماه، روز) - اطلاعات ثابت پیکربندی:
(server, port)
person = ("Ali", 25, "Tehran")
در اینجا person یک «رکورد» است؛ نام، سن و شهر با هم معنی پیدا میکنند و قرار نیست مدام عناصر این رکورد را حذف/اضافه کنیم.
چرا تاپل وقتی داده تغییر نمیکند بهتر است؟
- امنیت بیشتر: خودِ شما یا فانکشنهای دیگر نمیتوانند بهاشتباه آن را تغییر دهند.
- در وضعیتهای خاص (مباحث پیشرفتهتر)، استفاده از تاپل میتواند به بهینهسازی سرعت و حافظه کمک کند.
دیکشنری (`dict`) را چه زمانی انتخاب کنیم؟
ویژگی مهم: نگه داشتن داده بهصورت کلید → مقدار.
دیکشنری مناسب است وقتی:
- میخواهید به دادهها با یک عنوان/برچسب معنادار دسترسی داشته باشید، نه با عدد.
- دادهها ماهیت «مشخصات» دارند: مثل نام، سن، شهر، شماره دانشجویی، …
student = {
"name": "Sara",
"age": 20,
"city": "Mashhad"
}اینجا:
"name","age","city"→ کلیدها"Sara",20,"Mashhad"→ مقدارها
بهتر است دیکشنری را انتخاب کنید اگر:
- زیاد میخواهید بپرسید: «سن سارا چنده؟»، «شهرش کجاست؟»
یعنی دسترسی سریع بر اساس کلید، نه موقعیت عددی. - مجموعهٔ بزرگی از «اشیاء» دارید و برای هرکدام میخواهید تعدادی ویژگی ذخیره کنید.
مثلاً فهرست دانشآموزان یک کلاس، که هر دانشآموز خودش یکdictباشد.
مثال کاربردی:
- نگهداشتن تنظیمات برنامه:
config = {
"theme": "dark",
"language": "fa",
"autosave": True
}- نگهداشتن موجودی یک فروشگاه (نام کالا → تعداد):
inventory = {
"apple": 20,
"banana": 35,
"orange": 12
}مجموعه (`set`) را چه زمانی انتخاب کنیم؟
ویژگی مهم:
بدون ترتیب مشخص، بدون تکرار، مناسب برای کار با «عضویت» و «اشتراک/اتحاد».
اگر مسئلهٔ شما بیشتر شبیه این سؤالهاست:
- «این عضو توی مجموعه هست یا نه؟»
- «عناصر مشترک بین این دو گروه چی هستند؟»
- «میخواهم لیستی از آیتمها را بگیرم و تکراریها را حذف کنم.»
آنوقت set انتخاب خوبی است.
مثالها:
- لیست ایمیلهای واردشده توسط کاربر، اما هر ایمیل فقط یکبار:
emails = ["a@test.com", "b@test.com", "a@test.com"]
unique_emails = set(emails) # تکراریها حذف میشوند- پیدا کردن کتابهای مشترک دو نفر:
ali_books = {"Python", "C++", "Linux"}
sara_books = {"Python", "HTML", "CSS"}
common = ali_books & sara_books # اشتراکset را انتخاب کنید اگر:
- به ترتیب اهمیتی نمیدهید.
- نمیخواهید عنصر تکراری داشته باشید.
- زیاد عمل «عضو هست / نیست» انجام میدهید:
x in my_set.
جدول مقایسهٔ سریع
| ویژگی / نوع داده | list | tuple | dict | set |
|---|---|---|---|---|
| ترتیب حفظ میشود؟ | بله | بله | (نسخههای جدید: بله) | نه (برای ما مهم نیست) |
| قابلتغییر است؟ | بله | نه | بله | بله |
| اجازهٔ تکرار دارد؟ | بله | بله | کلید: نه، مقدار: بله | نه |
| دسترسی اصلی | اندیس (۰،۱،۲,…) | اندیس | کلید ("name", "age") | بررسی عضویت (in) |
| کاربرد معمول | فهرست، صف، تاریخچه | رکورد ثابت، مختصات | مشخصات، تنظیمات، نگاشتها | مجموعهٔ یکتا، عملیات ریاضی مجموعهها |
الگوهای رایج تصمیمگیری
۱. فهرست اشیاء در مقابل دیکشنریِ اشیاء
فرض کنید یک سیستم برای مدیریت کتابخانه مینویسید.
- اگر فقط میخواهید فهرست کتابها را نگه دارید:
books = ["Book A", "Book B", "Book C"] # لیست ساده- اگر هر کتاب چند ویژگی دارد (نام، نویسنده، سال چاپ):
book1 = {
"title": "Book A",
"author": "Author A",
"year": 2020
}- اگر چندین کتاب دارید، معمولاً لیستی از دیکشنریها میسازید:
books = [
{"title": "Book A", "author": "Author A", "year": 2020},
{"title": "Book B", "author": "Author B", "year": 2018},
]پس:
- «فهرست چیزها» →
list - «مشخصات هر چیز» →
dict - «لیستِ مشخصاتِ چیزها» →
listی ازdictها
۲. انتخاب بین list و set در مسئلهٔ عضویت
سناریو: میخواهید چک کنید آیا یک کاربر عضو لیست کاربران مسدودشده هست یا نه.
- اگر تعداد کم است و موضوع تکراریبودن مهم نیست →
listکافی است. - اگر تعداد زیاد است، تکرارینبودن مهم است، و مرتباً میپرسید «فلانی توی لیست هست؟» →
setمناسبتر است.
blocked_users = {"ali", "sara", "mina"} # set
if username in blocked_users:
print("دسترسی مسدود است.")۳. استفاده از tuple بهجای list برای دادهٔ ثابت
اگر مختصات چند نقطه را ذخیره میکنید، و نمیخواهید نقاط تغییر کنند:
point = (10, 20) # بهتر از [10, 20] اگر قرار نیست تغییر کنددر عوض، برای لیست مسیر حرکت (که تغییر میکند و عناصر جدید اضافه میشوند):
path = [] # شروع خالی
path.append((0, 0))
path.append((1, 2))اینجا:
- خود
pathیکlistاست (قابلتغییر). - هر نقطه داخل آن، یک
tupleاست (ثابت).
چند سناریوی تمرینی ذهنی
در هر سناریو، سعی کنید قبل از دیدن پاسخ، حدس بزنید از چه ساختاری استفاده میکنید.
سناریو ۱: فهرست کارهای روزانه
- هر کار فقط یک متن کوتاه است (مثلاً «خرید نان»).
- میخواهید ترتیب اضافهشدن کارها حفظ شود.
- ممکن است همان کار را چند بار در روز یادداشت کنید.
انتخاب: list
مثال:
tasks = ["خرید نان", "مطالعهٔ پایتون", "ورزش"]سناریو ۲: اطلاعات دانشآموز
- برای یک دانشآموز: نام، سن، شماره دانشآموزی، شهر.
- میخواهید با اسم ویژگی به آنها دسترسی داشته باشید.
انتخاب: dict برای هر دانشآموز.
اگر چند دانشآموز دارید، میتوانید:
listی ازdictها،- یا
dictی ازdictها (مثلاً کلید بیرونی = شماره دانشآموزی) استفاده کنید.
سناریو ۳: مجموعهٔ یکتای برچسبها (Tags)
- کاربران میتوانند روی یک نوشته، برچسبهایی مثل
"python","beginner","code"بگذارند. - مهم است که یک برچسب تکراری نشود.
انتخاب: set برای برچسبهای هر نوشته.
tags = {"python", "beginner", "code"}سناریو ۴: روزهای هفته
- نام روزهای هفته که همیشه ثابت هستند و تغییری نمیکنند.
- ممکن است بخواهید رویشان حلقه بزنید، اما نه اضافه و نه حذف.
انتخاب: tuple (یا حتی list، اما tuple معنای «ثابت»بودن را بهتر منتقل میکند):
week_days = ("شنبه", "یکشنبه", "دوشنبه", "سهشنبه", "چهارشنبه", "پنجشنبه", "جمعه")راهنمای کوتاه «اگر … پس …»
- اگر فقط یک لیست ساده از چیزها میخواهم و ممکن است تغییر کند →
list - اگر یک بسته/رکورد ثابت از چند مقدار دارم →
tuple - اگر ویژگیها را با نامهای معنیدار ذخیره میکنم →
dict - اگر فقط یکتا بودن و عضویت مهم است →
set - اگر چند چیز و برای هر چیز چند ویژگی دارم → معمولاً
listی ازdictها - اگر میخواهم به چیزها با شناسهٔ یکتا دسترسی سریع داشته باشم (مثلاً
id) → احتمالاًdict(کلید = شناسه)
با تمرین و نوشتن برنامههای بیشتر، انتخاب ساختار داده بهمرور برایتان طبیعی میشود. در ابتدای کار اگر شک داشتید، از list شروع کنید و بعد از کمی تجربه، اگر دیدید الگوی استفادهتان بیشتر شبیه dict یا set است، ساختار را عوض کنید.