آموزش پایتون, پایتون سطح متوسط

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

دیکشنری در پایتون

🗓 آخرین به‌روزرسانی:

دیکشنری یکی از مهم‌ترین ساختارهای داده در پایتون برای ذخیره اطلاعات به‌صورت کلید و مقدار است. برخلاف لیست که برای دسترسی به عناصر از شماره اندیس استفاده می‌کند، در دیکشنری هر مقدار با یک نام یا کلید مشخص شناسایی می‌شود. به همین دلیل دیکشنری برای نگهداری اطلاعاتی مانند مشخصات کاربر، جزئیات محصول، تنظیمات برنامه و رکوردهای ساختاریافته بسیار مناسب است.

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

فهرست مطالب
  1. دیکشنری در پایتون چیست؟
  2. ویژگی‌های اصلی دیکشنری‌ها
  3. ساخت دیکشنری در پایتون
  4. کلیدهای معتبر در دیکشنری
  5. کلیدهای دیکشنری باید یکتا باشند
  6. دسترسی به مقدار با کلید
  7. خطای KeyError چیست؟
  8. دسترسی امن با متد get
  9. بررسی وجود کلید با in
  10. تغییر مقدار یک کلید
  11. افزودن کلید و مقدار جدید
  12. به‌روزرسانی با متد update
  13. تعداد جفت‌های کلید–مقدار با len
  14. دریافت همه کلیدها با keys
  15. دریافت همه مقدارها با values
  16. دریافت کلید و مقدار با items
  17. پیمایش دیکشنری با حلقه for
  18. حذف یک جفت با pop
  19. حذف آخرین جفت با popitem
  20. حذف با del
  21. خالی‌کردن دیکشنری با clear
  22. کپی‌کردن دیکشنری
  23. ساخت دیکشنری با fromkeys
  24. متد setdefault
  25. دیکشنری تو‌در‌تو
  26. لیستی از دیکشنری‌ها
  27. تبدیل دو لیست به دیکشنری با zip
  28. دیکشنری‌کامپرهنشن
  29. مقایسه دیکشنری با لیست
  30. مقایسه دیکشنری با تاپل
  31. مثال کاربردی: محاسبه قیمت سبد خرید
  32. مثال کاربردی: شمارش تکرار کلمات
  33. پروژه اول: دفترچه تلفن ساده
  34. پروژه دوم: مدیریت موجودی کالا
  35. خطاهای رایج هنگام کار با دیکشنری
  36. تمرین‌های پیشنهادی
  37. پرسش‌های متداول
  38. جمع‌بندی
  39. ادامه مسیر یادگیری پایتون

دیکشنری در پایتون چیست؟

دیکشنری یا 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)

مقایسه دیکشنری با لیست

ویژگیDictionaryList
نوع دسترسیبا کلیدبا اندیس عددی
ساختارکلید و مقداردنباله عناصر
کلید یکتاداردمفهوم کلید ندارد
مقدار تکراریمجاز استمجاز است
قابل تغییربلهبله
کاربرد اصلیاطلاعات نام‌دار و ساختاریافتهمجموعه مرتب از عناصر

برای مثال، نمایش اطلاعات کاربر با دیکشنری خواناتر است:

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() یا روش‌های مناسب دیگر استفاده کنید.

تمرین‌های پیشنهادی

  1. دیکشنری مشخصات یک کتاب شامل عنوان، نویسنده، قیمت و وضعیت موجودی بسازید.
  2. قیمت یک محصول را در دیکشنری تغییر دهید و کلید تخفیف را اضافه کنید.
  3. برنامه‌ای بنویسید که یک کلید را از کاربر بگیرد و مقدار آن را با get() نمایش دهد.
  4. همه کلیدها، مقدارها و جفت‌های یک دیکشنری را جداگانه پیمایش کنید.
  5. دو لیست نام و نمره را با zip() به دیکشنری تبدیل کنید.
  6. با دیکشنری‌کامپرهنشن، عددهای ۱ تا ۱۰ و مکعب آن‌ها را ذخیره کنید.
  7. برنامه‌ای بنویسید که تعداد تکرار هر حرف یک متن را محاسبه کند.
  8. دیکشنری تو‌در‌تویی برای سه دانش‌آموز و نمره‌های آن‌ها بسازید.
  9. برنامه دفترچه تلفن را به امکان ویرایش شماره مجهز کنید.
  10. سیستم موجودی کالا را طوری توسعه دهید که افزودن کالای جدید نیز ممکن باشد.

📌 همچنین بخوانید: بازار کار پایتون در ایران، دستورهای break، continue و pass در پایتون و ساخت ربات تلگرام با پایتون

پرسش‌های متداول

آیا دیکشنری اندیس عددی دارد؟

خیر. دسترسی مستقیم با کلید انجام می‌شود. برای دریافت یک کلید براساس موقعیت می‌توان ابتدا کلیدها را به لیست تبدیل کرد، اما این روش معمولاً هدف اصلی دیکشنری نیست.

تفاوت get و کروشه چیست؟

کروشه در صورت نبودن کلید خطای KeyError ایجاد می‌کند، اما get() مقدار None یا مقدار پیش‌فرض تعیین‌شده را برمی‌گرداند.

آیا مقدارهای دیکشنری باید یکتا باشند؟

خیر. فقط کلیدها باید یکتا باشند و مقدارها می‌توانند تکراری باشند.

آیا می‌توان دیکشنری را داخل دیکشنری قرار داد؟

بله. دیکشنری‌های تو‌در‌تو برای نمایش اطلاعات ساختاریافته و چندسطحی بسیار کاربردی هستند.

آیا ترتیب دیکشنری حفظ می‌شود؟

در پایتون‌های جدید، ترتیب درج جفت‌های کلید–مقدار حفظ می‌شود. بااین‌حال، هدف اصلی دیکشنری دسترسی براساس کلید است.

جمع‌بندی

در این درس یاد گرفتیم دیکشنری داده‌ها را به‌صورت کلید و مقدار ذخیره می‌کند. با روش‌های ساخت دیکشنری، دسترسی امن با get()، افزودن و تغییر مقدارها، حذف داده، پیمایش با keys()، values() و items()، دیکشنری‌های تو‌در‌تو، دیکشنری‌کامپرهنشن و کاربردهای عملی آشنا شدیم.

در درس بعدی دوره متوسط، با مجموعه یا Set در پایتون آشنا می‌شویم و یاد می‌گیریم چگونه مقدارهای تکراری را حذف و عملیات اجتماع، اشتراک و تفاضل مجموعه‌ها را انجام دهیم.

ادامه مسیر یادگیری پایتون

برای یادگیری منظم، آموزش‌های مرتبط زیر را به‌ترتیب دنبال کنید:

می‌خواهی پیشرفتت ذخیره شود؟با ورود یا ثبت‌نام رایگان، درس‌های تمام‌شده را علامت بزن و درصد پیشرفتت را در حساب کاربری ببین.ورود / ثبت‌نام برای ذخیره پیشرفت
درس بعدی · دوره پایتون متوسط (3 از 18)مجموعه یا Set در پایتون؛ حذف مقادیر تکراری و عملیات مجموعه‌ها ←
آموزش‌های تازه، کد آماده و رفع خطاهر هفته در کانال Dev Source؛ رایگان.
🧭 مسیر یادگیری پایتون از صفر
ماژول 5: ساختارهای داده — درس 20 از 44

برای ذخیره پیشرفت در همه دستگاه‌ها و دریافت گواهی پایان مسیر، رایگان ثبت‌نام کن یا وارد شو.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *