Найти в Дзене
Codeville | Python | SQL

Словари (dict). Ключ/значение. Распаковка. Методы.

Что же такое словари такое и где они используются? Очередная незаурядная структура данных, которая нужна непонятно для чего? Ответ: нет. В Python ничего не бывает просто так. Словарям можно найти уйму применений начиная от структуры данных, которая хранит в себе данные о пользователях заканчивая созданием «объектов» на их основе. Давайте научимся их применять, но перед этим немного матчасти. Давайте посмотрим на следующий код. Вот такие «фокусы» со словарями мы сможем делать в самом конце, когда поймём что такое значения, что такое ключи, поймём, как распаковать словарь по переменным и разберёмся с некоторым количеством методов, которые нам жизненно необходимы, если мы решили обращаться со словарями. Ключ/значение Думаю, что всякий хотя бы раз держал в руках толковый словарь, когда искал непонятное ему слово. Каждому слову в подобных словарях соответствует какое-то значение, трактовка. Со словарями в Python ситуация ровно такая же, потому что у нас есть ключ — «идентификатор», котором
Оглавление

Что же такое словари такое и где они используются? Очередная незаурядная структура данных, которая нужна непонятно для чего?

Ответ: нет. В Python ничего не бывает просто так. Словарям можно найти уйму применений начиная от структуры данных, которая хранит в себе данные о пользователях заканчивая созданием «объектов» на их основе. Давайте научимся их применять, но перед этим немного матчасти.

Давайте посмотрим на следующий код.

Вот такие «фокусы» со словарями мы сможем делать в самом конце, когда поймём что такое значения, что такое ключи, поймём, как распаковать словарь по переменным и разберёмся с некоторым количеством методов, которые нам жизненно необходимы, если мы решили обращаться со словарями.

Ключ/значение

Думаю, что всякий хотя бы раз держал в руках толковый словарь, когда искал непонятное ему слово. Каждому слову в подобных словарях соответствует какое-то значение, трактовка. Со словарями в Python ситуация ровно такая же, потому что у нас есть ключ — «идентификатор», которому соответствует какое-то значение.

Давайте посмотрим на пример:

d = {1: 'Vasya', 2: 'Kolya', 3: 'Dmitry'}

Хочу заметить, что словарь обрамляется в фигурные скобки, таков его синтаксис. У меня есть материал по поводу синтаксиса словарей, я выделил 5 способов их задания, можете ознакомиться с этим материалом по ссылке

Есть ключи, которым соответствуют какие-то значения. В нашем случае ключу «1» соответствует значение 'Vasya', ключу «2» — 'Kolya' и так далее. Не правда ли очень похоже на настоящий бумажный словарь?

Ключи и значения отделяются двоеточием, чтобы интерпретатор Python понимал, что есть что. Кроме того, данный пример замечательно иллюстрирует определение словарей. Давайте посмотрим.

Словари - упорядоченные коллекции произвольных объектов с доступом по ключу. Объектом мы зовём всякую сущность, относящуюся к какому-либо классу (типу), будь то строка, число или что-то подобное.

Что же иллюстрирует созданный словарь? Он прекрасно иллюстрирует определение упорядоченности, т.к. наши ключи — это числа, начинающиеся с единицы. У нас есть порядок ключей, от 1 до 3.

Как же обращаться к значениям в словаре? Очень просто, этот процесс напоминает обращение по индексу в списке или строке. Нам всего лишь нужно обратиться к словарю и в квадратных скобках указать ключ того значения, к которому мы хотим обратиться. Внимание на пример:

d = {1: 'Vasya', 2: 'Kolya', 3: 'Dmitry'}
print(d[1]) # 'Vasya'
print(d[3]) # 'Dmitry'

Ключом может быть не только число, но и строка в том числе.

d = {'1': 'Vasya', '2': 'Kolya', '3': 'Dmitry'}

В таком случае при обращении к значению по ключу мы будем использовать не число, а строку.

print(d['1']) # 'Vasya'
print(d['3']) # 'Dmitry'

Распаковка значений или ключей словаря.

Например, у нас есть какой-то словарь, значения в котором мы хотим распределить по каким-то переменным.

Забегая наперёд расскажу и двух методах словарей: values() и keys(). Полагаю, что интуитивно понятно по названиям, что они делают: values() возвращает все значения в словаре в виде списка, а keys() — ключи. Давайте посмотрим на пример.

d = {'one': 'Dmitry', 'two': 'Gennadiy', 'three': 'Anton'}
print(d.values()) # dict_values(['Dmitry', 'Gennadiy', 'Anton'])
print(d.keys()) # dict_keys(['one', 'two', 'three'])

Так вот, в Python реализована такая вещь, как распаковка. В нашем случае values() и keys() возвращают список со значениями и ключами соответственно, а списки являются распаковываемыми, так что давайте посмотрим на то, как это делается на примере выше.

name1, name2, name3 = d.values()
print(name1) # 'Dmitry'
print(name2) # 'Gennadiy'
print(name3) # 'Anton'

Таким образом мы «распределили» три элемента списка со значениями словаря по трём переменным: name1, name2, name3.

Хочу заметить, что если бы мы попытались распределить наш список со значениями словаря по четырём переменным, то с учётом того, что значений в списке со значениями всего три, мы бы получили следующую ошибку:

name1, name2, name3, name4= d.values()
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
name1, name2, name3, name4 = d.values()
ValueError: not enough values to unpack (expected 4, got 3)

Эта ошибка говорит о том, что в списке недостаточно значений для распаковки по переменным name1, name2, name3 и name4 в силу того, что мы имеем 4 переменные и 3 распаковываемых значения в списке.

А что, если нас интересует, например, только первое и последнее значение из списка значений словаря? Давайте немного изменим наш исходный словарь, увеличив количество ключзначений в нём.

d = {'one': 'Dmitry', 'two': 'Gennadiy', 'three': 'Anton', 'four': 'Anna', 'five': 'Victor', 'six': 'Max'}

Из данного словаря мы хотим «вытащить» значения 'Dmitry' и 'Max'. Мы можем сделать 6 переменных и распаковать в них массив, а потом взять первое и последнее значения по именам переменных:

name1, name2, name3, name4, name5, name6 = d.values()
print(name1) # 'Dmitry'
print(name6) # 'Max'

Да, такое сработает, но, во-первых, это не слишком-то лаконично и просто, писать много кода — это как-то не «по-питонистски», а, во-вторых, не слишком оптимизированно по памяти, т.к. нам приходится выделять целых 6 переменных для записи значений.

Если мы желаем вытащить первое и последнее значение и при этом не потерять остальные, а сохранить их в виде списка где-то ещё, чтобы использовать, например, в дальнейшем, то мы можем использовать следующий код:

d = {'one': 'Dmitry', 'two': 'Gennadiy', 'three': 'Anton', 'four': 'Anna', 'five': 'Victor', 'six': 'Max'}
first_name, *other_names, last_name = d.values()

Что означает «звёздочка» перед переменной other_names? Логика следующая: интерпретатор читает имена переменных и ищет там подобные особенности и если видит подобную конструкцию, то записывает первое значение списка d.values() в первую переменную first_name, последнее значение — в переменную last_name, а всё остальное — в переменную other_name.

Более наглядно это будет проиллюстрировано на следующем примере, где мы будем записывать в первые 2 переменные первые 2 имени, а всё остальное отправим в третью, как информацию, которая нас сейчас не особо интересует, но в будущем обязательно понадобится.

d = {'one': 'Dmitry', 'two': 'Gennadiy', 'three': 'Anton', 'four': 'Anna', 'five': 'Victor', 'six': 'Max'}
first, second, *other = d.values()
print(first) # 'Dmitry'
print(second) 'Gennadiy'
print(other) # ['Anton', 'Anna', 'Victor', 'Max']

Методы

d.clear() - очищает словарь

d = {1: 'one', 2: 'two', 3: 'three'}
d.clear()
print(d) # {}

d.copy() - возвращает копию словаря.

d = {1: 'one', 2: 'two', 3: 'three'}
d1 = d.copy()
print(d1) # {1: 'one', 2: 'two', 3: 'three'}

d.get(key,default) - возвращает значение ключа, но если его нет, не бросает исключение, а возвращает default (по умолчанию None).

d = {1: 'one', 2: 'two', 3: 'three'}
print(d.get(1)) one
print(d.get(4,'Not found')) Not found

d.items() - возвращает пары (ключ, значение).

d = {1: 'one', 2: 'two', 3: 'three'}
print(d.items()) # dict_items([(1, 'one'), (2, 'two'), (3, 'three')])

d.keys() - возвращает ключи в словаре.

d.values() - возвращает значения в словаре.

d.pop(key, default) - удаляет ключ и возвращает значение. Если ключа нет, возвращает default (по умолчанию бросает исключение).

d = {1: 'one', 2: 'two', 3: 'three'}
print(d.pop(1)) # 'one'
print(d.pop(4,'Not Found')) # 'Not Found'

d.popitem() - удаляет крайний правый ключзначение и возвращает пару (ключ, значение). Если словарь пуст, вызывает исключение KeyError.

d = {1: 'one', 2: 'two', 3: 'three'}
print(d.popitem()) # (3, 'three')
print(d) # {1: 'one', 2: 'two'}
print(d.popitem()) # (2, 'two')
print(d) # {1: 'one'}

d.update([other]) - обновляет словарь, добавляя пары (ключ, значение) из other. Существующие ключи перезаписываются.

d = {1: 'one', 2: 'two', 3: 'three'}
d.update({4: 'four'})
print(d) # {1: 'one', 2: 'two', 3: 'three', 4: 'four'}
d.update({2: 'four'})
print(d) # {1: 'one', 2: 'four', 3: 'three', 4: 'four'}

Теперь обратимся к примеру в самом начале и посмотрим, что он из себя представляет.

-2

Что же здесь происходит? У нас имеется словарь user_data, в котором содержатся ключи и значения этих ключей — это тоже словари, в которых содержатся поля имени, фамилии, возраста и страны проживания. Подумайте над этим и перечитайте то, что я написал выше ещё раз, если возникло недопонимание.

Если мы выполним следующий код, то программа выведет словарь, «объект», который будет содержать данные о пользователе.

print(user_data[1]) # {'name': 'Vasya', 'surname': 'Ivanov', 'age': 22, 'country': 'Russia'}

Теперь давайте обратимся к значениям этого словаря в словаре, имеющего ключ «1».

print(user_data[1].values()) # dict_values(['Vasya', 'Ivanov', 22, 'Russia'])

Мы получаем список, который в последней строке на скриншоте выше распаковывается по переменным name, surname, age, county.

name, surname, age, country = user_data[1].values()
print(name) # 'Vasya'
print(surname) 'Ivanov'
print(age) 22
print(country) 'Russia'

Ссылка на файл из скриншота: тык