دیکشنری در پایتون؛ ذخیره اطلاعات بهصورت کلید و مقدار

🗓 آخرین بهروزرسانی:
دیکشنری یکی از مهمترین ساختارهای داده در پایتون برای ذخیره اطلاعات بهصورت کلید و مقدار است. برخلاف لیست که برای دسترسی به عناصر از شماره اندیس استفاده میکند، در دیکشنری هر مقدار با یک نام یا کلید مشخص شناسایی میشود. به همین دلیل دیکشنری برای نگهداری اطلاعاتی مانند مشخصات کاربر، جزئیات محصول، تنظیمات برنامه و رکوردهای ساختاریافته بسیار مناسب است.
این مطلب، درس دوم از دوره رایگان پایتون سطح متوسط است. در درس قبلی با تاپلها و تفاوت آنها با لیست آشنا شدیم. اکنون یاد میگیریم چگونه دادهها را با ساختار کلید–مقدار سازماندهی کنیم.
فهرست مطالب
- دیکشنری در پایتون چیست؟
- ویژگیهای اصلی دیکشنریها
- ساخت دیکشنری در پایتون
- کلیدهای معتبر در دیکشنری
- کلیدهای دیکشنری باید یکتا باشند
- دسترسی به مقدار با کلید
- خطای KeyError چیست؟
- دسترسی امن با متد get
- بررسی وجود کلید با in
- تغییر مقدار یک کلید
- افزودن کلید و مقدار جدید
- بهروزرسانی با متد update
- تعداد جفتهای کلید–مقدار با len
- دریافت همه کلیدها با keys
- دریافت همه مقدارها با values
- دریافت کلید و مقدار با items
- پیمایش دیکشنری با حلقه for
- حذف یک جفت با pop
- حذف آخرین جفت با popitem
- حذف با del
- خالیکردن دیکشنری با clear
- کپیکردن دیکشنری
- ساخت دیکشنری با fromkeys
- متد setdefault
- دیکشنری تودرتو
- لیستی از دیکشنریها
- تبدیل دو لیست به دیکشنری با zip
- دیکشنریکامپرهنشن
- مقایسه دیکشنری با لیست
- مقایسه دیکشنری با تاپل
- مثال کاربردی: محاسبه قیمت سبد خرید
- مثال کاربردی: شمارش تکرار کلمات
- پروژه اول: دفترچه تلفن ساده
- پروژه دوم: مدیریت موجودی کالا
- خطاهای رایج هنگام کار با دیکشنری
- تمرینهای پیشنهادی
- پرسشهای متداول
- جمعبندی
- ادامه مسیر یادگیری پایتون
دیکشنری در پایتون چیست؟
دیکشنری یا dictionary مجموعهای از جفتهای کلید و مقدار است. هر کلید به یک مقدار مرتبط میشود:
user = {
"name": "Mehran",
"age": 30,
"city": "Istanbul"
}
print(user)در این دیکشنری:
"name"یک کلید و"Mehran"مقدار مرتبط با آن است."age"کلید دیگری است که مقدار30را نگهداری میکند."city"به مقدار"Istanbul"متصل است.
کلید و مقدار با علامت دونقطه : از هم جدا میشوند و جفتهای مختلف با ویرگول تفکیک میشوند.
ویژگیهای اصلی دیکشنریها
- کلیدها یکتا هستند: یک کلید نمیتواند همزمان دو مقدار مستقل داشته باشد.
- مقادیر میتوانند تکراری باشند: چند کلید میتوانند مقدار یکسان داشته باشند.
- قابل تغییر هستند: میتوان مقدارها را اضافه، ویرایش یا حذف کرد.
- دسترسی با کلید انجام میشود: برای دریافت یک مقدار از نام کلید استفاده میکنیم.
- ترتیب درج حفظ میشود: در نسخههای جدید پایتون، ترتیب ورود جفتهای کلید–مقدار حفظ میشود.
- مقادیر میتوانند هر نوع دادهای باشند: متن، عدد، لیست، تاپل، دیکشنری و حتی مقدار بولی.
ساخت دیکشنری در پایتون
رایجترین روش ساخت دیکشنری استفاده از آکولاد است:
product = {
"name": "laptop",
"price": 35000,
"in_stock": True
}ساخت دیکشنری خالی
user = {}
print(user)
print(type(user))خروجی:
{}
<class 'dict'>همچنین میتوان از تابع dict() استفاده کرد:
settings = dict()ساخت دیکشنری با تابع dict
تابع dict() میتواند با آرگومانهای نامگذاریشده یک دیکشنری بسازد:
user = dict(name="Sara", age=27, city="Tehran")
print(user)خروجی:
{'name': 'Sara', 'age': 27, 'city': 'Tehran'}در این روش، کلیدها بهصورت رشته ذخیره میشوند.
کلیدهای معتبر در دیکشنری
کلیدهای دیکشنری باید از نوع دادههای غیرقابلتغییر و قابل هش باشند. انواع رایج کلید عبارتاند از:
- رشته
- عدد صحیح یا اعشاری
- مقدار بولی
- تاپل، به شرطی که عناصر آن نیز قابل هش باشند
data = {
"name": "Ali",
1: "number one",
(35.7, 51.4): "coordinates"
}لیست و دیکشنری نمیتوانند کلید باشند، زیرا قابل تغییر هستند:
data = {
[1, 2]: "value"
}این کد خطای زیر را ایجاد میکند:
TypeError: unhashable type: 'list'کلیدهای دیکشنری باید یکتا باشند
اگر یک کلید چند بار نوشته شود، آخرین مقدار جایگزین مقدار قبلی میشود:
user = {
"name": "Ali",
"name": "Reza"
}
print(user)خروجی:
{'name': 'Reza'}بنابراین برای جلوگیری از حذف ناخواسته داده، باید نام کلیدها را با دقت انتخاب کنیم.
دسترسی به مقدار با کلید
برای دریافت مقدار یک کلید، نام دیکشنری و سپس کلید را داخل کروشه مینویسیم:
user = {
"name": "Mehran",
"age": 30,
"city": "Istanbul"
}
print(user["name"])
print(user["age"])خروجی:
Mehran
30خطای KeyError چیست؟
اگر کلیدی که وجود ندارد با کروشه درخواست شود، پایتون خطای KeyError ایجاد میکند:
user = {"name": "Mehran"}
print(user["email"])KeyError: 'email'برای دسترسی امنتر میتوان از متد get() استفاده کرد.
دسترسی امن با متد get
user = {"name": "Mehran", "age": 30}
print(user.get("name"))
print(user.get("email"))خروجی:
Mehran
Noneاگر کلید وجود نداشته باشد، get() بهجای ایجاد خطا مقدار None برمیگرداند.
تعیین مقدار پیشفرض در get
user = {"name": "Mehran"}
email = user.get("email", "No email on file")
print(email)خروجی:
No email on fileبررسی وجود کلید با in
user = {"name": "Mehran", "age": 30}
if "age" in user:
print("Age is on file")عملگر in در حالت عادی کلیدهای دیکشنری را بررسی میکند، نه مقدارها را.
بررسی نبودن کلید
if "email" not in user:
print("No email on file")تغییر مقدار یک کلید
دیکشنری قابل تغییر است. برای ویرایش مقدار، کلید را در سمت چپ علامت مساوی قرار میدهیم:
product = {
"name": "book",
"price": 120000
}
product["price"] = 135000
print(product)خروجی:
{'name': 'book', 'price': 135000}افزودن کلید و مقدار جدید
اگر کلید در دیکشنری وجود نداشته باشد، انتساب مقدار یک جفت جدید میسازد:
user = {"name": "Sara"}
user["age"] = 27
user["city"] = "Tehran"
print(user)بهروزرسانی با متد update
متد update() میتواند یک یا چند کلید را اضافه یا ویرایش کند:
product = {
"name": "headphones",
"price": 900000
}
product.update({
"price": 850000,
"in_stock": True
})
print(product)کلید price ویرایش و کلید in_stock اضافه میشود.
تعداد جفتهای کلید–مقدار با len
user = {
"name": "Ali",
"age": 25,
"city": "Shiraz"
}
print(len(user))خروجی:
3دریافت همه کلیدها با keys
user = {
"name": "Ali",
"age": 25,
"city": "Shiraz"
}
print(user.keys())خروجی مشابه زیر است:
dict_keys(['name', 'age', 'city'])خروجی keys() یک نمای پویا از کلیدهاست. برای تبدیل آن به لیست میتوان نوشت:
key_list = list(user.keys())دریافت همه مقدارها با values
print(user.values())خروجی:
dict_values(['Ali', 25, 'Shiraz'])دریافت کلید و مقدار با items
print(user.items())خروجی:
dict_items([('name', 'Ali'), ('age', 25), ('city', 'Shiraz')])هر جفت بهصورت یک تاپل دوتایی ارائه میشود.
پیمایش دیکشنری با حلقه for
پیمایش کلیدها
user = {
"name": "Ali",
"age": 25,
"city": "Shiraz"
}
for key in user:
print(key)این حلقه بهطور پیشفرض کلیدها را پیمایش میکند.
پیمایش مقدارها
for value in user.values():
print(value)پیمایش همزمان کلید و مقدار
for key, value in user.items():
print(key, ":", value)متد items() در هر دور یک تاپل شامل کلید و مقدار تولید میکند و آن را باز میکنیم.
حذف یک جفت با pop
user = {
"name": "Maryam",
"age": 29,
"city": "Tabriz"
}
removed_age = user.pop("age")
print(removed_age)
print(user)متد pop() مقدار کلید حذفشده را نیز برمیگرداند.
استفاده امن از pop
اگر کلید وجود نداشته باشد، pop() خطای KeyError ایجاد میکند؛ مگر اینکه مقدار پیشفرض بدهیم:
email = user.pop("email", "Not found")
print(email)حذف آخرین جفت با popitem
product = {
"name": "mouse",
"price": 500000,
"color": "black"
}
last_item = product.popitem()
print(last_item)
print(product)متد popitem() آخرین جفت اضافهشده را حذف و بهصورت تاپل برمیگرداند.
حذف با del
user = {"name": "Sara", "age": 27}
del user["age"]
print(user)اگر کلید وجود نداشته باشد، دستور del نیز خطای KeyError ایجاد میکند.
خالیکردن دیکشنری با clear
settings = {
"theme": "dark",
"language": "fa"
}
settings.clear()
print(settings)خروجی:
{}کپیکردن دیکشنری
انتساب ساده یک کپی مستقل ایجاد نمیکند:
original = {"name": "Ali", "age": 25}
copy_data = original
copy_data["age"] = 30
print(original)هر دو متغیر به یک دیکشنری اشاره میکنند؛ بنابراین مقدار اصلی نیز تغییر میکند.
کپی سطحی با copy
original = {"name": "Ali", "age": 25}
copy_data = original.copy()
copy_data["age"] = 30
print(original)
print(copy_data)برای دادههای ساده، این روش یک کپی مستقل میسازد. در ساختارهای تودرتو، copy() فقط کپی سطحی ایجاد میکند.
ساخت دیکشنری با fromkeys
fields = ["name", "email", "phone"]
contact = dict.fromkeys(fields, "Not set")
print(contact)خروجی:
{'name': 'Not set', 'email': 'Not set', 'phone': 'Not set'}نکته: هنگام استفاده از یک مقدار قابل تغییر مانند لیست در fromkeys()، همه کلیدها به همان شیء اشاره میکنند. برای ساخت لیستهای مستقل بهتر است از روش دیگری مانند دیکشنریکامپرهنشن استفاده شود.
متد setdefault
متد setdefault() اگر کلید وجود داشته باشد مقدار فعلی آن را برمیگرداند؛ در غیر این صورت کلید را با مقدار پیشفرض اضافه میکند:
user = {"name": "Reza"}
city = user.setdefault("city", "Tehran")
print(city)
print(user)اگر دوباره همان کلید را با مقدار دیگری فراخوانی کنیم، مقدار موجود تغییر نمیکند:
user.setdefault("city", "Shiraz")
print(user["city"])دیکشنری تودرتو
مقدار یک کلید میتواند دیکشنری دیگری باشد:
users = {
"user_1": {
"name": "Ali",
"age": 25
},
"user_2": {
"name": "Sara",
"age": 28
}
}
print(users["user_1"]["name"])برای دسترسی به دادههای داخلی، کلیدها را پشت سر هم مینویسیم.
پیمایش دیکشنری تودرتو
for user_id, info in users.items():
print("ID:", user_id)
print("Name:", info["name"])
print("Age:", info["age"])لیستی از دیکشنریها
یکی از رایجترین ساختارها در برنامههای واقعی، لیستی از دیکشنریهاست:
products = [
{"name": "book", "price": 120000},
{"name": "notebook", "price": 80000},
{"name": "pencil", "price": 15000}
]
for product in products:
print(product["name"], product["price"])این ساختار برای دادههای JSON، پاسخ API و رکوردهای پایگاه داده بسیار رایج است.
تبدیل دو لیست به دیکشنری با zip
keys = ["name", "age", "city"]
values = ["Maryam", 29, "Tabriz"]
user = dict(zip(keys, values))
print(user)تابع zip() عناصر همجایگاه را به هم متصل میکند و dict() آنها را به دیکشنری تبدیل میکند.
دیکشنریکامپرهنشن
مانند لیستکامپرهنشن، میتوان با یک عبارت کوتاه دیکشنری ساخت:
squares = {number: number ** 2 for number in range(1, 6)}
print(squares)خروجی:
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}دیکشنریکامپرهنشن با شرط
even_squares = {
number: number ** 2
for number in range(1, 11)
if number % 2 == 0
}
print(even_squares)مقایسه دیکشنری با لیست
| ویژگی | Dictionary | List |
|---|---|---|
| نوع دسترسی | با کلید | با اندیس عددی |
| ساختار | کلید و مقدار | دنباله عناصر |
| کلید یکتا | دارد | مفهوم کلید ندارد |
| مقدار تکراری | مجاز است | مجاز است |
| قابل تغییر | بله | بله |
| کاربرد اصلی | اطلاعات نامدار و ساختاریافته | مجموعه مرتب از عناصر |
برای مثال، نمایش اطلاعات کاربر با دیکشنری خواناتر است:
user = {
"name": "Mehran",
"age": 30,
"city": "Istanbul"
}در مقابل، این لیست نیازمند بهخاطر سپردن جایگاه هر مقدار است:
user = ["Mehran", 30, "Istanbul"]مقایسه دیکشنری با تاپل
- دیکشنری با کلید و تاپل با اندیس دسترسی میدهد.
- دیکشنری قابل تغییر و تاپل غیرقابلتغییر است.
- دیکشنری برای اطلاعات دارای نام مناسبتر است.
- تاپل برای دادههای مرتب و ثابت مانند مختصات مناسبتر است.
مثال کاربردی: محاسبه قیمت سبد خرید
cart = {
"book": 120000,
"notebook": 80000,
"pencil": 15000
}
total = 0
for product, price in cart.items():
print(product, price)
total += price
print("Total:", total)مثال کاربردی: شمارش تکرار کلمات
text = "python code python dictionary code python"
words = text.split()
word_count = {}
for word in words:
word_count[word] = word_count.get(word, 0) + 1
print(word_count)در هر دور، اگر کلمه قبلاً وجود داشته باشد تعداد آن افزایش پیدا میکند؛ در غیر این صورت مقدار اولیه صفر در نظر گرفته میشود.
پروژه اول: دفترچه تلفن ساده
در این پروژه، نام مخاطب کلید و شماره تلفن مقدار است:
contacts = {}
while True:
print("\n1. Add contact")
print("2. Search contact")
print("3. Show all contacts")
print("4. Delete contact")
print("5. Exit")
choice = input("Your choice: ").strip()
if choice == "1":
name = input("Contact name: ").strip()
phone = input("Phone number: ").strip()
contacts[name] = phone
print("Contact saved.")
elif choice == "2":
name = input("Contact name: ").strip()
phone = contacts.get(name)
if phone is None:
print("Contact not found.")
else:
print("Phone:", phone)
elif choice == "3":
if len(contacts) == 0:
print("The phone book is empty.")
else:
for name, phone in contacts.items():
print(name, ":", phone)
elif choice == "4":
name = input("Contact name to delete: ").strip()
removed_phone = contacts.pop(name, None)
if removed_phone is None:
print("Contact not found.")
else:
print("Contact deleted.")
elif choice == "5":
print("Goodbye!")
break
else:
print("Invalid option.")پروژه دوم: مدیریت موجودی کالا
inventory = {
"book": 10,
"notebook": 15,
"pencil": 30
}
while True:
product_name = input("Item name or exit: ").strip()
if product_name.lower() == "exit":
break
if product_name not in inventory:
print("This item does not exist.")
continue
try:
quantity = int(input("Quantity sold: "))
except ValueError:
print("Quantity must be a whole number.")
continue
if quantity <= 0:
print("Quantity must be greater than zero.")
elif quantity > inventory[product_name]:
print("Not enough stock.")
else:
inventory[product_name] -= quantity
print("Remaining stock:", inventory[product_name])
print("Final stock:")
for name, quantity in inventory.items():
print(name, quantity)خطاهای رایج هنگام کار با دیکشنری
۱. دسترسی به کلید ناموجود
user["email"]برای جلوگیری از KeyError از get() یا بررسی in استفاده کنید.
۲. استفاده از لیست بهعنوان کلید
data[[1, 2]] = "value"کلید باید قابل هش و غیرقابلتغییر باشد.
۳. اشتباهگرفتن پیمایش کلید و مقدار
for item in user:
print(item)این کد کلیدها را چاپ میکند. برای مقدارها از values() و برای هر دو از items() استفاده کنید.
۴. تغییر اندازه دیکشنری هنگام پیمایش
حذف یا افزودن کلیدها هنگام پیمایش مستقیم ممکن است خطا ایجاد کند:
for key in data:
if data[key] == 0:
del data[key]راه امنتر پیمایش روی یک کپی از کلیدهاست:
for key in list(data.keys()):
if data[key] == 0:
del data[key]۵. تصور اینکه get کلید را میسازد
متد get() فقط مقدار را میخواند و در صورت نبودن کلید، آن را اضافه نمیکند. برای ساخت مقدار پیشفرض از انتساب، setdefault() یا روشهای مناسب دیگر استفاده کنید.
تمرینهای پیشنهادی
- دیکشنری مشخصات یک کتاب شامل عنوان، نویسنده، قیمت و وضعیت موجودی بسازید.
- قیمت یک محصول را در دیکشنری تغییر دهید و کلید تخفیف را اضافه کنید.
- برنامهای بنویسید که یک کلید را از کاربر بگیرد و مقدار آن را با
get()نمایش دهد. - همه کلیدها، مقدارها و جفتهای یک دیکشنری را جداگانه پیمایش کنید.
- دو لیست نام و نمره را با
zip()به دیکشنری تبدیل کنید. - با دیکشنریکامپرهنشن، عددهای ۱ تا ۱۰ و مکعب آنها را ذخیره کنید.
- برنامهای بنویسید که تعداد تکرار هر حرف یک متن را محاسبه کند.
- دیکشنری تودرتویی برای سه دانشآموز و نمرههای آنها بسازید.
- برنامه دفترچه تلفن را به امکان ویرایش شماره مجهز کنید.
- سیستم موجودی کالا را طوری توسعه دهید که افزودن کالای جدید نیز ممکن باشد.
📌 همچنین بخوانید: بازار کار پایتون در ایران، دستورهای break، continue و pass در پایتون و ساخت ربات تلگرام با پایتون
پرسشهای متداول
آیا دیکشنری اندیس عددی دارد؟
خیر. دسترسی مستقیم با کلید انجام میشود. برای دریافت یک کلید براساس موقعیت میتوان ابتدا کلیدها را به لیست تبدیل کرد، اما این روش معمولاً هدف اصلی دیکشنری نیست.
تفاوت get و کروشه چیست؟
کروشه در صورت نبودن کلید خطای KeyError ایجاد میکند، اما get() مقدار None یا مقدار پیشفرض تعیینشده را برمیگرداند.
آیا مقدارهای دیکشنری باید یکتا باشند؟
خیر. فقط کلیدها باید یکتا باشند و مقدارها میتوانند تکراری باشند.
آیا میتوان دیکشنری را داخل دیکشنری قرار داد؟
بله. دیکشنریهای تودرتو برای نمایش اطلاعات ساختاریافته و چندسطحی بسیار کاربردی هستند.
آیا ترتیب دیکشنری حفظ میشود؟
در پایتونهای جدید، ترتیب درج جفتهای کلید–مقدار حفظ میشود. بااینحال، هدف اصلی دیکشنری دسترسی براساس کلید است.
جمعبندی
در این درس یاد گرفتیم دیکشنری دادهها را بهصورت کلید و مقدار ذخیره میکند. با روشهای ساخت دیکشنری، دسترسی امن با get()، افزودن و تغییر مقدارها، حذف داده، پیمایش با keys()، values() و items()، دیکشنریهای تودرتو، دیکشنریکامپرهنشن و کاربردهای عملی آشنا شدیم.
در درس بعدی دوره متوسط، با مجموعه یا Set در پایتون آشنا میشویم و یاد میگیریم چگونه مقدارهای تکراری را حذف و عملیات اجتماع، اشتراک و تفاضل مجموعهها را انجام دهیم.
ادامه مسیر یادگیری پایتون
برای یادگیری منظم، آموزشهای مرتبط زیر را بهترتیب دنبال کنید:
برای ذخیره پیشرفت در همه دستگاهها و دریافت گواهی پایان مسیر، رایگان ثبتنام کن یا وارد شو.