Методы словарей и операции над словарями в Python
У класса dict
есть классовый метод fromkeys(iterable[, value])
, с помощью которого создается новый словарь, ключи которого берутся из переданного в метод итерируемого объекта. Значениями всех ключей по-умолчанию является None
или передаваемое вторым аргументом значение.
letters = 'aeiyou'
nums = [5, 8, 9, 3]
words = ('cat', 'dog', 'pig')
dl = dict.fromkeys(letters, 0)
dn = dict.fromkeys(nums)
dw = dn.fromkeys(words, 'gray')
print(dl)
print(dn)
print(dw)
{'a': 0, 'e': 0, 'i': 0, 'y': 0, 'o': 0, 'u': 0}
{5: None, 8: None, 9: None, 3: None}
{'cat': 'gray', 'dog': 'gray', 'pig': 'gray'}
Методы экземпляра словаря keys()
, values()
, items()
возвращают особые типы объектов - dictionary view objects - объекты просмотра словаря. Эти объекты являются итерируемыми.
d = {'cat': 5, 'dog': 3, 'pig': 1}
dk = d.keys()
dv = d.values()
di = d.items()
print(dk)
print(dv)
print(di)
for k, v in di:
print(k, '=', v)
print(list(dk))
print(tuple(dv))
dict_keys(['cat', 'dog', 'pig'])
dict_values([5, 3, 1])
dict_items([('cat', 5), ('dog', 3), ('pig', 1)])
cat = 5
dog = 3
pig = 1
['cat', 'dog', 'pig']
(5, 3, 1)
Важной особенностью экземпляров просмотра словаря является то, что они остаются "связанными" со своим словарем. Поэтому любые изменения последнего отражаются в этих объектах.
d = {'cat': 5, 'dog': 3, 'pig': 1}
di = d.items()
dv = d.values()
print(list(di))
print(sum(list(dv)))
d['cow'] = 1
d['pig'] += 1
print(list(di))
print(sum(list(dv)))
[('cat', 5), ('dog', 3), ('pig', 1)]
9
[('cat', 5), ('dog', 3), ('pig', 2), ('cow', 1)]
11
Если подобная связь не требуется, то список всех ключей словаря может быть удобнее получать с помощью встроенной функции list(iterable=())
.
>>> d = {'cat': 5, 'dog': 3, 'pig': 1}
>>> k = list(d)
>>> k
['cat', 'dog', 'pig']
>>> d['cow'] = 1
>>> k
['cat', 'dog', 'pig']
Если требуется очистить содержимое словаря без удаления самого словаря, следует использовать метод clear()
.
d = {'cat': 5, 'dog': 3, 'pig': 1}
print(d)
print('Number of entries:', len(d))
d.clear()
print(d)
print('Number of entries:', len(d))
{'cat': 5, 'dog': 3, 'pig': 1}
Number of entries: 3
{}
Number of entries: 0
Просто удалить любую запись словаря, обращаясь к ней по ключу, можно с помощью оператора del
, который в классе dict
перегружается методом __delitem__(self, key)
. Если записи с указанным ключом нет, будет выбрашено исключение KeyError
.
>>> a = dict(cat=3, dog=5, pig=1)
>>> a
{'cat': 3, 'dog': 5, 'pig': 1}
>>> del a['cat']
>>> a.__delitem__('pig')
>>> a
{'dog': 5}
>>> del a['cow']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'cow'
В отличие от del
метод pop(key[, default])
не только удаляет запись из словаря по ключу, но и возвращает значение этой записи. Если переданного методу ключа нет в словаре, то в качестве значения возвращается default, если он был указан, или выбрасывается KeyError
.
d = {'cat': 5, 'dog': 3, 'pig': 1}
s = sum(list(d.values()))
print(s) # 9
s -= d.pop('dog')
print(s) # 6
s -= d.pop('cow', 0)
print(s) # 6
s -= d.pop('pig', 0)
print(s) # 5
Метод popitem()
не принимает аргументов, удаляет из словаря последнюю запись, возвращает ее в виде кортежа, в котором первый элемент представляет собой ключ, второй - значение. Вызов метода на пустой словарь приводит к выбросу KeyError
.
d = {'cat': 5, 'dog': 3, 'pig': 1}
while len(d) != 0:
print(d.popitem())
('pig', 1)
('dog', 3)
('cat', 5)
Метод get(key, default=None)
возвращает значение указанного ключа, также как и обычное получение из словаря значения по ключу через квадратные скобки. Однако данный метод никогда не возбуждает KeyError
и поэтому может быть предпочтительным в ряде случаев. Значение default возвращается, когда ключа нет в словаре. Вместо None
можно указать свое значение.
d = {'cat': 5, 'dog': 3, 'pig': 1}
for i in range(4):
print(d.get(input('Pet: ')))
Pet: dog
3
Pet: cow
None
Pet: pig
1
Pet: rabbit
None
По аналогии с этим при добавлении записи в словарь вместо нотации d[key] = value
можно использовать метод setdefault(key, default=None)
. Его отличительной особенностью является то, что если запись с таким ключом уже есть в словаре, ее значение не будет перезаписано. При этом метод возвращает значение ключа, по которому можно оценить, была ли добавлена новая запись, или она уже ранее присутствовала в словаре.
d = {'cat': 5, 'dog': 3, 'pig': 1}
n = d.setdefault('cow', 1)
print(n)
n = d.setdefault('dog', 1)
print(n)
print(d)
1
3
{'cat': 5, 'dog': 3, 'pig': 1, 'cow': 1}
Наличие записи в словаре можно проверить с помощью оператора in
.
d = {'cat': 5, 'dog': 3, 'pig': 1}
print('cat' in d) # True
print('cat' not in d) # False
print('cow' in d) # False
print('cow' not in d) # True
При присваивании другой переменной словарь не копируется, а создается вторая ссылка на него. Поэтому, чтобы скопировать словарь, следует использовать метод copy()
.
>>> first = {'a': 3, 'b': 5}
>>> second = first
>>> third = first.copy()
>>>
>>> second['c'] = 4
>>>
>>> first
{'a': 3, 'b': 5, 'c': 4}
>>> second
{'a': 3, 'b': 5, 'c': 4}
>>> third
{'a': 3, 'b': 5}
>>>
>>> id(first) == id(second)
True
>>> id(first) == id(third)
False
При этом метод copy()
выполняет поверхностное копирование. Это значит, что если какое-либо значение словаря является изменяемым типом, то его изменение в одном словаре отразится в другом.
>>> first = {'bread': [4, 28.5], 'milk': 6}
>>> second = first.copy()
>>>
>>> first['bread'][1] += 0.75
>>> first['milk'] = [6, 58]
>>>
>>> first
{'bread': [4, 29.25], 'milk': [6, 58]}
>>> second
{'bread': [4, 29.25], 'milk': 6}
С помощью метода update([other])
можно объединить два словаря в один или, используя итерируемый объект, добавить в словарь новые записи или обновить значения существующих. При совпадении ключей значения словаря, к которому применяется метод, перезаписываются на новые.
d = {'cat': 5, 'dog': 3}
print(d)
d.update({'dog': 1, 'pig': 2})
d.update([('rabbit', 4), ('sheep', 2)])
d.update(hen=8, cat=3, pig=5)
print(d)
{'cat': 5, 'dog': 3}
{'cat': 3, 'dog': 1, 'pig': 5, 'rabbit': 4, 'sheep': 2, 'hen': 8}