کلاس dict در پایتون متدهای مفید زیادی برای کار با دیکشنریها فراهم میکند.
برخی از آنها در مفهوم dict معرفی شدند.
در اینجا به چند مورد دیگر میپردازیم، همراه با چند تکنیک برای پیمایش و دستکاری دیکشنریها.
<dict>.setdefault() کلیدها را بهطور خودکار و بدون پرتاب KeyError اضافه میکند.<dict>.fromkeys(<iterable>, <default value>) از هر تعداد تکرارپذیر یک dict جدید میسازد.<dict>.keys()، <dict>.values() و <dict>.items() تکرارگرهای مناسبی فراهم میکنند.sorted(<dict>.items()) میتواند بهراحتی ترتیب ورودیهای یک dict را تغییر دهد.<dict_one>.update(<dict_two>) یک dict را با مقادیر همپوشان از dict دیگری بهروزرسانی میکند.<dict> | <other_dict> و <dict> |= <other_dict> دو dict را از طریق عملگرها ادغام یا بهروزرسانی میکنند.reversed(<dict>.keys())، reversed(<dict>.values()) یا reversed(<dict>.items()) نماهای معکوس تولید میکنند.<dict>.popitem() یک جفت key و value را حذف میکند و برمیگرداند.setdefault() برای درج بدون خطامفهوم دیکشنری پیشتر توضیح داده بود که <dict>.get(<key>, <default value>) یک value موجود را برمیگرداند، یا اگر key در دیکشنری پیدا نشود default value را، و بدین ترتیب از بروز KeyError جلوگیری میکند.
این کار در موقعیتهایی خوب جواب میدهد که ترجیح میدهید مدیریت خطای اضافی نداشته باشید، اما نمیتوانید مطمئن باشید که key مورد نظر وجود دارد.
برای یک عمل درج به همان اندازه «امن» (بدون KeyError)، متد <dict>.setdefault(<key>, <default value>) وجود دارد.
اگر key در دیکشنری پیدا شود، <dict>.setdefault(<key>, <default value>) مقدار value را برمیگرداند.
اگر کلید پیدا نشود، جفت (key، default value) را درج میکند و default value را برای استفاده برمیگرداند.
>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
# Looking for the value associated with key "Rock Brown".The key does not exist,
# so it is added with the default value, and the value is returned.
>>> palette.setdefault('Rock Brown', '#694605')
'#694605'
# The (key, default value) pair has now been added to the dictionary.
>>> palette_I
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Rock Brown': '#694605'}
fromkeys()
برای پر کردن سریع یک دیکشنری با keys و مقادیر پیشفرض مختلف، متد کلاس fromkeys(<iterable>, <default value>) روی یک تکرارپذیر از keys پیمایش میکند و یک dict جدید میسازد.
همهی values روی default value دادهشده تنظیم میشوند:
>>> new_dict = dict.fromkeys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'], 'fill in hex color here')
{'Grassy Green': 'fill in hex color here',
'Purple Mountains Majesty': 'fill in hex color here',
'Misty Mountain Pink': 'fill in hex color here'}
key، value) با .popitem()
.popitem() یک جفت (key، value) را از دیکشنری حذف میکند و برمیگرداند.
جفتها به ترتیب آخرین ورودی، اولین خروجی (LIFO) برگردانده میشوند.
اگر دیکشنری خالی باشد، فراخوانی popitem() یک KeyError ایجاد میکند:
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd'}
>>> palette_I.popitem()
('Misty Mountain Pink', '#f9c5bd')
>>> palette_I.popitem()
('Purple Mountains Majesty', '#8076a3')
>>> palette_I.popitem()
('Grassy Green', '#9bc400')
# All (key, value) pairs have been removed.
>>> palette_I.popitem()
Traceback (most recent call last):
line 1, in <module>
palette_I.popitem()
KeyError: 'popitem(): dictionary is empty'
متدهای .keys()، .values() و .items() نماهای تکرارپذیر یک دیکشنری را برمیگردانند.
با این نماها میتوان بهراحتی روی ورودیها حلقه زد بدون آنکه آنها را تغییر داد.
نماها همچنین پویا هستند: وقتی دادههای زیربنایی دیکشنری تغییر کند، view object مرتبط آن تغییر را نشان میدهد:
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd'}
# Using .keys() returns a list of keys.
>>> palette_I.keys()
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'])
# Using .values() returns a list of values.
>>> palette_I.values()
dict_values(['#9bc400', '#8076a3', '#f9c5bd'])
# Using .items() returns a list of (key, value) tuples.
>>> palette_I.items()
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', '#8076a3'), ('Misty Mountain Pink', '#f9c5bd')])
# Views are dynamic. Changing values in the dict
# changes all of the associated views.
>>> palette_I['Purple Mountains Majesty'] = (128, 118, 163)
>>> palette_I['Deep Red'] = '#932432'
>>> palette_I.values()
dict_values(['#9bc400', (128, 118, 163), '#f9c5bd', '#932432'])
>>> palette_I.keys()
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink', 'Deep Red'])
>>> palette_I.items()
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', (128, 118, 163)), ('Misty Mountain Pink', '#f9c5bd'), ('Deep Red', '#932432')])
.keys()، .values() و .items()
در پایتون ۳.۷+، dicts ترتیبی را که ورودیها درج شدهاند حفظ میکنند و این امکان را میدهند که هنگام استفاده از .keys()، .values() یا .items() به ترتیب اولین ورودی، اولین خروجی (FIFO) پیمایش کنید.
در پایتون ۳.۸+، نماها همچنین برگشتپذیر هستند.
این امکان را میدهد که کلیدها، مقادیر یا جفتهای (key، value) با استفاده از reversed(<dict>.keys())، reversed(<dict>.values()) یا reversed(<dict>.items()) به ترتیب آخرین ورودی، اولین خروجی (LIFO) پیمایش شوند:
>>> palette_II = {'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
>>> for item in palette_II.items():
... print(item)
...
('Factory Stone Purple', '#7c677f')
('Green Treeline', '#478559')
('Purple baseline', '#161748')
>>> for item in reversed(palette_II.items()):
... print(item)
...
('Purple baseline', '#161748')
('Green Treeline', '#478559')
('Factory Stone Purple', '#7c677f')
.update()
از <dict_one>.update(<dict_two>) میتوان برای ترکیب دو دیکشنری استفاده کرد.
این متد جفتهای (key,value) مربوط به <dict_two> را میگیرد و آنها را در <dict_one> مینویسد:
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd'}
>>> palette_II = {'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple Baseline': '#161748'}
>>> palette_I.update(palette_II)
# Note that new items from palette_II are added.
>>> palette_I
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple Baseline': '#161748'}
اگر کلیدها در دو دیکشنری همپوشانی داشته باشند، value در dict_one با value متناظر از dict_two بازنویسی میشود:
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
>>> palette_III = {'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189)}
>>> palette_I.update(palette_III)
# Overlapping values in palette_I are replaced with
# values from palette_III
>>> palette_I
{'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189),
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559', 'Purple baseline': '#161748'}
| و |=)پایتون ۳.۹ روش دیگری برای ادغام dicts معرفی میکند: عملگرهای union.
dict_one | dict_two یک دیکشنری جدید میسازد که از جفتهای (key، value) مربوط به dict_one و dict_two تشکیل شده است.
وقتی هر دو دیکشنری کلیدهای مشترک داشته باشند، مقادیر dict_two اولویت میگیرند.
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd'}
>>> palette_II = {'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
>>> new_dict = palette_I | palette_II
>>> new_dict
...
{'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
dict_one |= other رفتاری مشابه <dict_one>.update(<other>) دارد، اما در این حالت other میتواند یک dict یا یک تکرارپذیر از جفتهای (key، value) باشد:
>>> palette_III = {'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189)}
>>> new_dict |= palette_III
>>> new_dict
...
{'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189),
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
دیکشنریها متد مرتبسازی درونساخت ندارند.
با این حال، میتوان یک نمای dict را با تابع درونساخت sorted() همراه با .items() مرتب کرد.
سپس میتوان از نمای مرتبشده برای ساختن یک دیکشنری جدید استفاده کرد.
مگر اینکه یک کلید مرتبسازی مشخص شود، مرتبسازی پیشفرض بر اساس keys دیکشنری است.
# Default ordering for a dictionary is last in, first out (LIFO).
>>> color_palette = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
# The default sort order for a dictionary uses the keys.
>>> sorted_palette = dict(sorted(color_palette.items()))
>>> sorted_palette
{'Factory Stone Purple': '#7c677f',
'Grassy Green': '#9bc400',
'Green Treeline': '#478559',
'Misty Mountain Pink': '#f9c5bd',
'Purple Mountains Majesty': '#8076a3',
'Purple baseline': '#161748'}
# A sort key can be provided in the form
# of an anonymous function (lambda).
>>> value_sorted_palette = dict(sorted(color_palette.items(), key=lambda color: color[1]))
>>> value_sorted_palette
{'Purple baseline': '#161748',
'Green Treeline': '#478559',
'Factory Stone Purple': '#7c677f',
'Purple Mountains Majesty': '#8076a3',
'Grassy Green': '#9bc400',
'Misty Mountain Pink': '#f9c5bd'}
تعویض مطمئن کلیدها و مقادیر در یک دیکشنری کمی کار میبرد، اما میتوان آن را با یک loop و استفاده از dict.items() یا با یک درک دیکشنری انجام داد.
تعویض مطمئن فرض میکند که کلیدها و مقادیر dict هر دو هشپذیر باشند.
color_reference = {'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
# Creating a new dictionary to hold the swapped entries.
>>> swapped_color_reference = {}
# Iterating through the dictionary, using values as keys.
>>> for key, value in color_reference.items():
... swapped_color_reference[value] = key
>>> swapped_color_reference
{'#8076a3': 'Purple Mountains Majesty',
'#f9c5bd': 'Misty Mountain Pink',
'#7c677f': 'Factory Stone Purple',
'#478559': 'Green Treeline',
'#161748': 'Purple baseline'}
# A dictionary comprehension can also be used to swap entries.
>>> swapped = {value: key for key, value in
color_reference.items()}
>>> swapped
{'#8076a3': 'Purple Mountains Majesty',
'#f9c5bd': 'Misty Mountain Pink',
'#7c677f': 'Factory Stone Purple',
'#478559': 'Green Treeline',
'#161748': 'Purple baseline'}
اگر مقادیر ذخیرهشده در dict یکتا نباشند، پیش از انجام تعویض کلید و مقدار بررسیهای بیشتری لازم میشود:
# Things become more complicated if there are duplicates in
# potential key values.This dict is arranged by hex, RGB, and HSL
# keys, but values repeat.
>>> extended_colors = {'#8076a3': 'Purple Mountains Majesty',
(128, 118, 163): 'Purple Mountains Majesty',
(21, 28, 0, 36): 'Purple Mountains Majesty',
'#f9c5bd': 'Misty Mountain Pink',
(249, 197, 189): 'Misty Mountain Pink',
(0, 21, 24, 2): 'Misty Mountain Pink',
'#7c677f': 'Factory Stone Purple',
(124, 103, 127): 'Factory Stone Purple',
(2, 19, 0, 50): 'Factory Stone Purple',
'#478559': 'Green Treeline',
(71, 133, 89): 'Green Treeline',
(47, 0, 33, 48): 'Green Treeline'}
# New empty dictionary for holding swapped entries.
>>> consolidated_colors = {}
# Iterating over (key, value) pairs using .items()
>>> for key, value in extended_color_reference.items():
... if value in consolidated_colors: # <--Check if key has already been created.
... consolidated_colors[value].append(key)
... else:
... consolidated_colors[value] = [key] # <--Create a value list with the former key in it.
>>> consolidated_colors
{'Purple Mountains Majesty': ['#8076a3', (128, 118, 163), (21, 28, 0, 36)],
'Misty Mountain Pink': ['#f9c5bd', (249, 197, 189), (0, 21, 24, 2)],
'Factory Stone Purple': ['#7c677f', (124, 103, 127), (2, 19, 0, 50)],
'Green Treeline': ['#478559', (71, 133, 89), (47, 0, 33, 48)]}
برای توضیح دقیق دیکشنریها و متدهای کار با آنها، آموزش رسمی و مرجع رسمی کتابخانه نقاط شروع عالیای هستند.
Real Python و Finxter هم مقالات بسیار جامعی دربارهی دیکشنریهای پایتون دارند.
برای اطلاعات بیشتر دربارهی مرتبسازی، Sorting HOW TO را در مستندات پایتون ببینید.