مقدمه

در این درس، بررسی یکی دیگر از کالکشن‌های پایتون یعنی دیکشنری‌ها را شروع می‌کنیم. نوع dict در پایتون برای کار با کالکشن‌هایی که مقادیر key و value را نگه می‌دارند، تعریف شده است. این کالکشن‌ها از این جهت دیکشنری نامیده می‌شوند که ساختاری مشابه یک دیکشنری دارند؛ یعنی مقادیرشان به صورت جفت‌های key و value هستند. در این درس، تعریف و ویرایش دیکشنری‌ها و نحوه‌ی دسترسی به مقادیر آن را یاد می‌گیریم و بحث در مورد دیکشنری‌ها را با مطالبی مثل حلقه‌زدن روی دیکشنری‌ها در درس‌های بعدی ادامه می‌دهیم.

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

یک دیکشنری در پایتون، کالکشنی است که مقادیرش به صورت زوج‌های key-value هستند. دیکشنری هم مثل لیست، یک کالکشن تغییرپدیر است و همانطور که در طول این درس خواهیم دید، امکان ویرایش درجای آن در طول برنامه وجود دارد. اما بر خلاف لیست‌ها، دیکشنری‌ها کالکشن‌های غیرترتیبی هستند. ساختار کلی یک دیکشنری پایتون به صورت زیر است.

{key_1: value_1, key_2: value_2, ...., key_n: value_n}

در این ساختار:

  • کلیدها (keys) باید یکتا باشند؛ یعنی نمی‌توانیم دو کلید با مقدار یکسان داشته باشیم. در ضمن، نوع کلیدها معمولاً str است اما هر نوع تغییرناپذیر دیگر مثل int یا حتی tuple (به شرطی که عناصر تاپل هم از نوع‌های تغییرناپذیر باشند) هم می‌تواند کلید باشد.
  • مقادیر (values) می‌توانند از هر نوعی باشند و محدودیتی در این مورد نداریم. یک value در دیکشنری حتی می‌تواند یک کالکشن مثل لیست یا یک دیکشنری دیگر باشد.

برای ایجاد یک دیکشنری، می‌توانیم از آکلادها و یا تابع dict() استفاده کنیم. در مثال زیر، دیکشنری‌هایی با استفاده از هر دو روش، ایجاد شده است.

Copy Icon dictionaries.py
leo = {'name': 'Lionel Messi', 'nationality': 'Argentina', 'number': 10}
cr7 = {'name': 'Cristiano Ronaldo', 'nationality': 'Portugal', 'number': 7}

zizo = dict(name='Zinedine Zidane', nationality='France', number=10) 

pele = dict([('name', 'Edson Arantes Do Nascimento'), ('nationality', 'Brazil'), ('number', 10)])

در اینجا دو دیکشنری اول با استفاده از آکلادها ایجاد شده‌اند که سریع‌ترین و ساده‌ترین راه برای ایجاد دیکشنری‌هاست. دیکشنری سوم که zizo نام‌گذاری شده، با استفاده از تابع dict() ایجاد شده و دیکشنری آخر یعنی pele هم با استفاده از تابع dict() ایجاد شده اما با این تفاوت که این بار، آرگومان این تابع، یک لیست از تاپل‌هاست.

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

دسترسی به مفادیر ذخیره‌شده در یک دیکشنری از طریق کلیدها صورت می‌گیرد. برای دسترسی به مقدار متناظر با یک کلید، می‌توانیم آن کلید را درون براکت قرار دهیم و یا به عنوان آرگومان به متدی به نام get() بدهیم. در مثال زیر، از هر دو روش استفاده شده است.

Copy Icon dictionaries.py
leo = {'name': 'Lionel Messi', 'nationality': 'Argentina', 'number': 10}
cr7 = {'name': 'Cristiano Ronaldo', 'nationality': 'Portugal', 'number': 7}

zizo = dict(name='Zinedine Zidane', nationality='France', number=10) 

pele = dict([('name', 'Edson Arantes Do Nascimento'), ('nationality', 'Brazil'), ('number', 10)])

print(leo['name'])
print(cr7['nationality'])

print(zizo.get('name'))

نتیجه ی اجرای این کد به صورت زیر خواهد بود.

Lionel Messi 
Portugal 
Zinedine Zidane 
          

ویرایش دیکشنری‌ها

گفتیم که دیکشنری‌های پایتون، کالکشن‌هایی تغییرپذیر (mutable) هستند. یعنی تغییرات روی یک دیکشنری به صورت درجا روی آن اعمال می‌شود و نیازی به تخصیص مجدد مقدار جدید به یک متغیر نیست. اما در این بخش، می‌خواهیم انواع تغییرات ممکن روی دیکشنری‌ها را ببینیم. همانند آنچه در مورد لیست‌ها دیدیم، این تغییرات شامل اضافه یا حذف آیتم و یا ویرایش آیتم‌های موجود است.

اضافه کردن آیتم به دیکشنری

اضافه کردن یک جفت key-value به یک دیکشنریِ موجود، کار بسیار ساده‌ای است. این کار در مثال زیر انجام شده است.

Copy Icon dictionaries.py
person = {'name': 'Lale', 'age': 4}

person['country'] = 'Iran' 

print(person)
print(person['country'])

اگر این کد را اجرا کنید، نتیجه‌ی زیر را دریافت خواهید کرد.

{'name': 'Lale', 'age': 4, 'country': 'Iran'}
Iran 
          

ویرایش آیتم‌های دیکشنری

اگر بخواهیم مقدار جدیدی به یک کلید بدهیم، می‌توانیم همانند آنچه در مثال زیر دیده می‌شود، این کار را انجام دهیم.

Copy Icon dictionaries.py
person = {'name': 'Lale', 'age': 4} 

person['age'] = 5 

print(person)

نتیجه‌ی اجرای این کد به صورت زیر خواهد بود.

{'name': 'Lale', 'age': 5} 
          

حذف آیتم از دیکشنری

یکی دیگر از کارهای ویرایشی که می‌توان روی دیکشنری‌ها انجام داد، حذف آیتم‌هاست. حذف یک جفت key-value از دیکشنری به دو روش امکان‌پذیر است: یکی با استفاده از یک گزاره‌ی del و دیگری با استفاده از متد pop(). قبلاً بحث مشابهی در مورد حذف آیتم‌های یک لیست داشته‌ایم و بنابراین، باید تفاوت گزاره‌های del و متد pop() برایتان روشن باشد.

وقتی جفتی را با استفاده از متد pop() حذف کنیم، مقدار حذف‌شده توسط این متد برگردانده می‌شود. بنابراین، اگر بخواهیم از مقدار حذف‌شده در جایی دیگر استفاده کنیم، باید از متد pop() استفاده کنیم. مثال زیر را ببینید.

Copy Icon dictionaries.py
person = {'name': 'Lale', 'age': 4, 'country': 'Iran', 'language': 'python'} 

del person['country'] 
print(person) 

programming_language = person.pop('language') 
print(person) 
print(programming_language)

نتیجه ی اجرا این کد، به صورت زیر خواهد بود.

{'name': 'Lale', 'age': 4, 'language': 'python'} 
{'name': 'Lale', 'age': 4} 
python 
          

متد popitem

در مورد لیست‌ها دیدیم که استفاده از متد pop() بدون آرگومان، باعث می‌شود که آخرین آیتم لیست حذف شود. طبیعتاً چنین چیزی در مورد دیکشنری‌ها ممکن نیست؛ چون دیکشنری‌ها غیرترتیبی هستند و مفاهیمی مثل اولین و آخرین آیتم در آنها معنایی ندارد. اما از پایتون 3.7 به بعد، ما با یک تغییر در این‌باره مواجه هستیم و آن این است که ترتیب آیتم‌های دیکشنری حفظ می‌شود و به این ترتیب، دیکشنری‌ها یک ماهیت ترتیبی پیدا می‌کنند. به خاطر مسئله‌ی حفظ سازگاری با نسخه‌های قبلی (backward compatibility) امکان تغییر رفتار متد pop() برای دیکشنری‌ها وجود ندارد و به همین دلیل، متد دیگری به نام popitem() کار حذف آخرین آیتم دیکشنری را انجام می‌دهد.

در ضمن، متد clear() همه‌ی جفت‌های یک دیکشنری را حذف می‌کند و آن را به یک دیکشنری خالی تبدیل می‌کند. از این متد در مثال زیر استفاده شده است.

Copy Icon dictionaries.py
person = {'aname': 'Lale', 'age': 4}
person.clear() 
print(person)  # {}

کپی کردن دیکشنری‌ها

هنگام بررسی لیست‌ها، دیدیم که اگر یک لیست را به یک متغیر اختصاص دهیم، اتفاقی که رخ می‌دهد، یک کپی ضعیف (shallow copy) است و برای انجام یک کپی کامل (deep copy) از اسلایس‌‌ها استفاده کردیم. این موضوع در مورد دیکشنری‌ها هم صادق است؛ یعنی تخصیص یک دیکشنری به یک متغیر، باعث می‌شود که یک کپی ضعیف صورت گیرد. برای کپی کامل یک دیکشنری، می‌توانیم از متد copy() استفاده کنیم.

Copy Icon dictionaries.py
person = {'name': 'Lale', 'age': 4}
person_copy = person.copy()
person_copy['age'] = 5 

print(person['age'])  # 4

خروجی مثال بالا 4 است که نشان می‌دهد، یک کپی کامل صورت گرفته است. اگر کپیِ انجام‌شده از نوع ضعیف بود، باید تغییر دیکشنری person_copy روی دیکشنری person هم اتفاق می‌افتاد. اگر متد copy() را از مثال بالا حذف کنیم، یک کپی ضعیف رخ می‌دهد و خروجی برابر با 5 خواهد بود.