5.5 KiB
title | localeTitle |
---|---|
Python defaultdict | Python defaultdict |
Python defaultdict
Словарь - одна из наиболее используемых структур данных в Python. Словарь представляет собой неупорядоченный набор элементов, и мы обычно имеем ключи и значения, хранящиеся в словаре. Давайте рассмотрим несколько примеров того, как обычно используется словарь.
# dictionary declaration 1
dict1 = dict()
# dictionary declaration 2
dict2 = {}
# Add items to the dictionary
# The syntax to add and retrieve items is same for either of the two objects we defined above.
key = "X"
value = "Y"
dict1[key] = value
# The dictionary doesn't have any specific data-type.
# So, the values can be pretty diverse.
dict1[key] = dict2
Давайте посмотрим на некоторые способы поиска.
# Since "X" exists in our dictionary, this will retrieve the value
value = dict1[key]
# This key doesn't exist in the dictionary.
# So, we will get a `KeyError`
value = dict1["random"]
Избегайте KeyError: используйте функцию .get
В случае, если данный ключ не существует в словаре, Python будет бросать KeyError
. Для этого есть простой способ обхода. Давайте посмотрим, как мы можем избежать KeyError
используя встроенная функция .get
для словарей.
dict_ = {}
# Some random key
random_key = "random"
# The most basic way of doing this is to check if the key
# exists in the dictionary or not and only retrieve if the
# key exists. Otherwise not.
if random_key in dict_:
print(dict_[random_key])
else:
print("Key = {} doesn't exist in the dictionary".format(dict_))
Много раз мы нормально получаем значение по умолчанию, когда ключ не существует. Например, когда построение счетчика. Существует лучший способ получить значения по умолчанию из словаря в случае отсутствующие ключи, а не полагаться на стандартное if-else
.
# Let's say we want to build a frequency counter for items in the following array
arr = [1,2,3,1,2,3,4,1,2,1,4,1,2,3,1]
freq = {}
for item in arr:
# Fetch a value of 0 in case the key doesn't exist. Otherwise, fetch the stored value
freq[item] = freq.get(item, 0) + 1
Таким образом, get(<key>, <defaultval>)
- это удобная операция для получения значения по умолчанию для любого заданного ключа из словаря. Проблема с этим методом возникает, когда мы хотим иметь дело с изменяемыми структурами данных как значения, например, list
или set
.
dict_ = {}
# Some random key
random_key = "random"
dict_[random_key] = dict_.get(random_key, []).append("Hello World!")
print(dict_) # {'random': None}
dict_ = {}
dict_[random_key] = dict_.get(random_key, set()).add("Hello World!")
print(dict_) # {'random': None}
Вы видели проблему?
Новый set
или list
не привязаны к ключу словаря. Мы должны назначить новый list
или set
к ключу в случае отсутствия значения, а затем append
или add
соответственно. Лей смотрит на пример для этого.
dict_ = {}
dict_[random_key] = dict_.get(random_key, set())
dict_[random_key].add("Hello World!")
print(dict_) # {'random': set(['Hello World!'])}. Yay!
Избегайте KeyError: используйте defaultdict
Это работает большую часть времени. Однако есть лучший способ сделать это. Более pythonic
путь. defaultdict
является подклассом встроенного класса dict. defaultdict
просто присваивает значение по умолчанию, которое мы укажем в случае отсутствия ключа. Итак, два шага:
dict_[random_key] = dict_.get(random_key, set())
dict_[random_key].add("Hello World!")
теперь можно объединить в один шаг. Например, для
from collections import defaultdict
# Yet another random key
random_key = "random_key"
# list defaultdict
list_dict_ = defaultdict(list)
# set defaultdict
set_dict_ = defaultdict(set)
# integer defaultdict
int_dict_ = defaultdict(int)
list_dict_[random_key].append("Hello World!")
set_dict_[random_key].add("Hello World!")
int_dict_[random_key] += 1
"""
defaultdict(<class 'list'>, {'random_key': ['Hello World!']})
defaultdict(<class 'set'>, {'random_key': {'Hello World!'}})
defaultdict(<class 'int'>, {'random_key': 1})
"""
print(list_dict_, set_dict_, int_dict_)