Что может быть ключом словаря
Перейти к содержимому

Что может быть ключом словаря

  • автор:

Словари

В языке программирования Python словари (тип dict ) представляют собой еще одну разновидность структур данных наряду со списками и кортежами. Словарь — это изменяемый (как список) неупорядоченный (в отличие от строк, списков и кортежей) набор элементов «ключ:значение».

«Неупорядоченный» – значит, что последовательность расположения пар не важна, в следствие чего обращение к элементам по индексам невозможно.

В других языках структуры, схожие со словарями, называются по-другому. Например, в Java подобный тип данных называется отображением.

Чтобы представление о словаре стало более понятным, проведем аналогию с обычным словарем, например, англо-русским. На каждое английское слово в таком словаре есть русское слово-перевод: cat – кошка, dog – собака, table – стол и т. д. Если англо-русский словарь описать с помощью Python, то английские слова можно сделать ключами, а русские – их значениями:

{'cat': 'кошка', 'dog': 'собака', 'bird': 'птица'>

Обратите внимание, что для определения словаря используются фигурные скобки. Синтаксис словаря на Питоне описывается такой схемой:

В словаре доступ к значениям осуществляется не по индексам, а по ключам, которые заключаются в квадратные скобки (по аналогии с индексами списков):

>>> a['cat'] 'кошка' >>> a['bird'] 'птица'

Словари, как и списки, являются изменяемым типом данных: позволительно изменять, добавлять и удалять элементы (пары «ключ:значение»). Изначально словарь можно создать пустым (например, d = <> ) и потом заполнить его элементами. Добавление и изменение имеет одинаковый синтаксис: словарь[ключ] = значение . Ключ может быть как уже существующим (тогда происходит изменение значения), так и новым (происходит добавление элемента словаря). Удаление элемента осуществляется с помощью встроенной оператора del языка Python.

>>> a = <> >>> a[1] = 2.34 >>> a[2] = 4.88 >>> a >>> a[1] = 3.01 >>> a >>> del a[2] >>> a

В словаре не может быть двух элементов с одинаковыми ключами. Однако могут быть одинаковые значения у разных ключей.

Ключом может быть любой неизменяемый тип данных. Значением – любой тип данных. Значения словарей вполне могут быть структурами, например, другими словарями или списками.

>>> nums = >>> person1 = >>> person1['data'][0] 4

Перебор элементов словаря в цикле for

Элементы словаря перебираются в цикле for также, как элементы других сложных объектов. Однако «по-умолчанию» извлекаются только ключи:

>>> nums >>> for i in nums: . print(i) . 1 2 3

Но по ключам всегда можно получить значения:

>>> for i in nums: . print(nums[i]) . one two three

С другой стороны у словаря как класса есть метод items() , который создает особую структуру, состоящую из кортежей. Каждый кортеж включает ключ и значение:

>>> n = nums.items() >>> n dict_items([(1, 'one'), (2, 'two'), (3, 'three')])

В цикле for можно распаковывать кортежи, таким образом сразу извлекая как ключ, так и его значение:

>>> for key, value in nums.items(): . print(key, 'is', value) . 1 is one 2 is two 3 is three

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

>>> v_nums = [] >>> for v in nums.values(): . v_nums.append(v) . >>> v_nums ['one', 'two', 'three']

Методы словаря

Кроме рассмотренных выше трех методов items() , keys() и values() словари обладают еще восемью. Это методы clear() , copy() , fromkeys() , get() , pop() , popitem() , setdefault() , update() .

Метод clear() удаляет все элементы словаря, но не удаляет сам словарь. В итоге остается пустой словарь:

>>> nums >>> nums.clear() >>> nums <>

Словарь – это изменяемый тип данных. Следовательно, как и список он передается в функцию по ссылке. Поэтому иногда, чтобы избежать нежелательного изменения глобального словаря его копируют. Это делают и с другими целями.

>>> n1 = >>> n2 = n1 >>> n3 = n1.copy() >>> n2[‘c’] = 3 >>> n1 >>> n2 >>> n3

Метод fromkeys() позволяет создать словарь из списка, элементы которого становятся ключами. Применять метод можно как классу dict , так и к его объектам:

>>> a = [1, 2, 3] >>> c = dict.fromkeys(a) >>> c >>> d = dict.fromkeys(a, 10) >>> d

Метод get() позволяет получить элемент по его ключу:

>>> nums.get(1) 'one'

Метод pop() удаляет из словаря элемент по указанному ключу и возвращает значение удаленной пары. Метод popitem() не принимает аргумента, удаляет элемент по принципу «последним вошел, первым вышел» и возвращает его в программу в виде кортежа (ключ, значение) .

>>> nums = >>> nums.pop(1) ‘one’ >>> nums >>> nums.popitem() (3, ‘three’) >>> nums

С помощью setdefault() можно добавить элемент в словарь:

>>> nums.setdefault(4, ‘four’) ‘four’ >>> nums

Равносильно nums[4] = ‘four’ , если элемент с ключом 4 отсутствует в словаре. Если он уже есть, то nums[4] = ‘four’ перезапишет старое значение, setdefault() – нет.

С помощью update() можно добавить в словарь другой словарь:

>>> nums.update() >>> nums

Также метод обновляет значения существующих ключей. Включает еще ряд особенностей.

Практическая работа

  1. Создайте словарь, связав его с переменной school , и наполните данными, которые бы отражали количество учащихся в разных классах (1а, 1б, 2б, 6а, 7в и т. п.). Внесите изменения в словарь согласно следующему: а) в одном из классов изменилось количество учащихся, б) в школе появился новый класс, с) в школе был расформирован (удален) другой класс. Вычислите общее количество учащихся в школе.
  2. Напишите функцию, которая принимает один словарь, и возвращает другой, в котором ключами являются значения из первого словаря, а значениями – соответствующие им ключи. Создайте словарь, передайте его в функцию. Выведите на экран исходный и «перевернутый» словари.

Примеры решения и дополнительные уроки в pdf-версии курса

X Скрыть Наверх

Python. Введение в программирование

Что может быть ключом словаря

Обычные списки (массивы) представляют собой набор пронумерованных элементов, то есть для обращения к какому-либо элементу списка необходимо указать его номер. Номер элемента в списке однозначно идентифицирует сам элемент. Но идентифицировать данные по числовым номерам не всегда оказывается удобно. Например, маршруты поездов в России идентифицируются численно-буквенным кодом (число и одна буква), также численно-буквенным кодом идентифицируются авиарейсы, то есть для хранения информации о рейсах поездов или самолетов в качестве идентификатора удобно было бы использовать не число, а текстовую строку.

Структура данных, позволяющая идентифицировать ее элементы не по числовому индексу, а по произвольному, называется словарем или ассоциативным массивом. Соответствующая структура данных в языке Питон называется dict .

Рассмотрим простой пример использования словаря. Заведем словарь Capitals , где индексом является название страны, а значением — название столицы этой страны. Это позволит легко определять по строке с названием страны ее столицу.

# Создадим пустой словать Capitals Capitals = dict() # Заполним его несколькими значениями Capitals['Russia'] = 'Moscow' Capitals['Ukraine'] = 'Kiev' Capitals['USA'] = 'Washington' Countries = ['Russia', 'France', 'USA', 'Russia'] for country in Countries: # Для каждой страны из списка проверим, есть ли она в словаре Capitals if country in Capitals: print('Столица страны ' + country + ': ' + Capitals[country]) else: print('В базе нет страны c названием ' + country)

Итак, каждый элемент словаря состоит из двух объектов: ключа и значения. В нашем примере ключом является название страны, значением является название столицы. Ключ идентифицирует элемент словаря, значение является данными, которые соответствуют данному ключу. Значения ключей — уникальны, двух одинаковых ключей в словаре быть не может.

В жизни широко распространены словари, например, привычные бумажные словари (толковые, орфографические, лингвистические). В них ключом является слово-заголовок статьи, а значением — сама статья. Для того, чтобы получить доступ к статье, необходимо указать слово-ключ.

Другой пример словаря, как структуры данных — телефонный справочник. В нем ключом является имя, а значением — номер телефона. И словарь, и телефонный справочник хранятся так, что легко найти элемент словаря по известному ключу (например, если записи хранятся в алфавитном порядке ключей, то легко можно найти известный ключ, например, бинарным поиском), но если ключ неизвествен, а известно лишь значение, то поиск элемента с данным значением может потребовать последовательного просмотра всех элементов словаря.

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

В языке Питон ключом может быть произвольный неизменяемый тип данных: целые и действительные числа, строки, кортежи. Ключом в словаре не может быть множество, но может быть элемент типа frozenset : специальный тип данных, являющийся аналогом типа set , который нельзя изменять после создания. Значением элемента словаря может быть любой тип данных, в том числе и изменяемый.

Когда нужно использовать словари

  • Подсчет числа каких-то объектов. В этом случае нужно завести словарь, в котором ключами являются объекты, а значениями — их количество.
  • Хранение каких-либо данных, связанных с объектом. Ключи — объекты, значения — связанные с ними данные. Например, если нужно по названию месяца определить его порядковый номер, то это можно сделать при помощи словаря Num[‘January’] = 1; Num[‘February’] = 2; . .
  • Установка соответствия между объектами (например, “родитель—потомок”). Ключ — объект, значение — соответствующий ему объект.
  • Если нужен обычный массив, но масимальное значение индекса элемента очень велико, и при этом будут использоваться не все возможные индексы (так называемый “разреженный массив”), то можно использовать ассоциативный массив для экономии памяти.

Создание словаря

Пустой словарь можно создать при помощи функции dict() или пустой пары фигурных скобок <> (вот почему фигурные скобки нельзя использовать для создания пустого множества). Для создания словаря с некоторым набором начальных значений можно использовать следующие конструкции:

Capitals = Capitals = dict(Russia = 'Moscow', Ukraine = 'Kiev', USA = 'Washington') Capitals = dict([("Russia", "Moscow"), ("Ukraine", "Kiev"), ("USA", "Washington")]) Capitals = dict(zip(["Russia", "Ukraine", "USA"], ["Moscow", "Kiev", "Washington"])) print(Capitals)

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

Работа с элементами словаря

Основная операция: получение значения элемента по ключу, записывается так же, как и для списков: A[key] . Если элемента с заданным ключом нет в словаре, то возникает исключение KeyError .

Другой способ определения значения по ключу — метод get : A.get(key) . Если элемента с ключом get нет в словаре, то возвращается значение None . В форме записи с двумя аргументами A.get(key, val) метод возвращает значение val , если элемент с ключом key отсутствует в словаре.

Проверить принадлежность элемента словарю можно операциями in и not in , как и для множеств.

Для добавления нового элемента в словарь нужно просто присвоить ему какое-то значение: A[key] = value .

Для удаления элемента из словаря можно использовать операцию del A[key] (операция возбуждает исключение KeyError , если такого ключа в словаре нет. Вот два безопасных способа удаления элемента из словаря.

A = key = 'ac' if key in A: del A[key] try: del A[key] except KeyError: print('There is no element with key "' + key + '" in dict') print(A)

В первом случае мы предварительно проверяем наличие элемента, а во втором — перехватываем и обрабатываем исключение.

Еще один способ удалить элемент из словаря: использование метода pop : A.pop(key) . Этот метод возвращает значение удаляемого элемента, если элемент с данным ключом отсутствует в словаре, то возбуждается исключение. Если методу pop передать второй параметр, то если элемент в словаре отсутствует, то метод pop возвратит значение этого параметра. Это позволяет проще всего организовать безопасное удаление элемента из словаря: A.pop(key, None) .

Перебор элементов словаря

Можно легко организовать перебор ключей всех элементов в словаре:

A = dict(zip('abcdef', list(range(6)))) for key in A: print(key, A[key])

Следующие методы возвращают представления элементов словаря. Представления во многом похожи на множества, но они изменяются, если менять значения элементов словаря. Метод keys возвращает представление ключей всех элементов, метод values возвращает представление всех значений, а метод items возвращает представление всех пар (кортежей) из ключей и значений.

Соответственно, быстро проверить, есть ли значение val среди всех значений элементов словаря A можно так: val in A.values() , а организовать цикл так, чтобы в переменной key был ключ элемента, а в переменной val , было его значение можно так:

A = dict(zip('abcdef', list(range(6)))) for key, val in A.items(): print(key, val)

dict (словарь)

obj — Первым необязательным позиционным аргументом может являться отображение или итерирующийся объект (при этом каждый его элемент должен быть тоже итерирующемся и содержать ровно два объекта).

**kwargs — Поддерживаются также необязательные именованные аргументы. При использовании вкупе с позиционными аргументами и совпадении ключей значениями из именованных пользуются приоритетом.

Словари являются отображениями.
Словари являются изменяемыми объектами.

Объявление

В коде словари могут быть объявлены при помощи фигурных скобок — <> .

 my_dict = 'key': 'value', 
'sub_dict': <>,
2: [1, 2, 3, 4],
>

# Словарь как слияние других словарей
dict_one =
dict_two =

my_dict = **dict_one,
**dict_two,
> #

Кроме того, можно объявить их при помощи конструктора dict().

 # Пустой словарь. 
my_dict = dict()

# Словарь из итерирующегося объекта.
my_dict = dict(zip(['one', 'two', 'three'], [1, 2, 3]))

# Словарь из именованных аргументов.
my_dict = dict(one=1, two=2, three=3)

# Словарь из списка кортежей.
my_dict = dict([('two', 2), ('one', 1), ('three', 3)])
Ключи

Ключами словаря могут являться только объекты, поддерживающие хеширование. Таким образом, использовать в качестве ключей списки, словари и другие изменяемые типы не получится.

Если в словарь будут добавлены несколько значений с одним и тем же ключом, словарь сохранит последнее.

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

Порядок ключей
Данные в обычном словаре упорядочены по очередности добавления ключей, начиная с +py3.6 (в +py2.7 — не упорядочены, но последовательность детерминирована, воспроизводима; в +py3.5 — не упорядочены, последовательность не детерминирована, не воспроизводима между запусками).

Если требуется хранить порядок, в котором в словарь были добавлены элементы (например для обхода этих элементов), следует использовать collections.OrderedDict().

Значения

В качестве значений могут использоваться любые объекты.

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

Если ключ отсутствует в словаре, возбуждается исключение KeyError.
+py2.5 Чтобы изменить это поведение можно в наследнике dict определить метод __missing__(key), в котором описать нужные действия при отсутствии ключа.

 my_dict =  
my_value = my_dict['key'] # value

Установка значений
Кроме установки значений при создании словаря, можно дополнять его по мере надобности.

 my_dict =  
my_dict['new_key'] = 'new_value' # Добавляем новый элемент словаря.
Определение наличия/отсутствия элемента

+py2.2 Определить, присутствует ли ключ в словаре можно при помощи конструкции in.
+py2.2 Определить, отсутствует ли ключ в словаре можно при помощи антонимичной конструкции not in.

 my_dict = 

# in
# Ключ 'key' существует, поэтому 'my_key_present' True
my_key_present = 'key' in my_dict
# Ключ 'another_key' отсутствует в словаре, поэтому 'my_key_present' False
my_key_present = 'another_key' in my_dict

# not in
# Ключ 'key' существует, поэтому 'my_key_absent' False
my_key_absent = 'key' not in my_dict
# Ключ 'another_key' отсутствует в словаре, поэтому 'my_key_absent' True
my_key_absent = 'another_key' not in my_dict
Количество элементов в словаре

Количество элементов можно получить, используя функцию len().

 my_dict =  
my_dict_length = len(my_dict) # 1
Детали реализации CPython

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

Для каждого ключа при помощи функции hash() вычисляется хеш-код. Код этот широко варьируется в зависимости от ключа и данных процесса (например, хеш для «Python» может быть -539294296 , в то время как для «python» — отличается от первого одним битом — он будет 1142331976 ). Хеш используется для определения места (во внутреннем массиве), где хранится значение. В случае если все используемые вами ключи будут иметь различные хеши, для получения значения по ключу будет затрачено постоянное время — O(1).

На заметку

О сложности основных операций для данного типа можно узнать из статьи «Сложность операций со словарями».

Словари

Словари — еще один встроенный тип данных для хранения объектов. Они используются для связывания одного объекта, называемого ключом, с другим, называемым значением. Такое связывание называется отображением. Результатом отображения будет пара ключ-значение. Пары ключ-значение добавляются в словарь. Затем вы можете найти в словаре ключ и получить соответствующее ему значение. Однако нельзя, наоборот, использовать значение для нахождения ключа.

Словари, как и списки, изменяемы. То есть, в них можно добавлять новые пары ключ-значение. Их полезность заключается в связях между ключами и значениями — существует множество ситуаций, в которых вам потребуется сохранять данные попарно. Например, в словаре можно сохранить информацию о телефонных номерах ваших друзей:

phones =
"Иван": "+7123456789",
"Василий": "+37520123456"
>
print(phones)

При создании словаря нужно использовать фигурные скобки, отделять ключ от значения двоеточием, а пары ключ-значение разделять запятыми. В отличие от кортежей, если у вас есть только одна пара ключ-значение, запятая после нее не нужна.

Как только вы создали словарь, можете добавлять в него пары ключ-значение, используя синтаксис имя\_словаря[ключ] = значение , а также искать значение при помощи ключа, используя синтаксис имя_словаря[ключ] .

phones =
"Иван": "+7123456789",
"Василий": "+37520123456"
>
phones['Григорий'] = 1234567890
print(phones['Иван'])

Значением в словаре может быть любой объект. В предыдущем примере первые два значения были строками, а последнее значение, 1234567890 , — целым числом.

В отличие от значения словаря, ключ словаря должен быть неизменяемым. Ключом словаря может быть строка или кортеж, но не список или словарь. Для определения того, есть ли ключ в словаре, используйте ключевое слово in , а not in — для проверки отсутствия ключа.

phones =
"Иван": "+7123456789",
"Василий": "+37520123456"
>
print("Василий" in phones) # True

Из словаря можно удалить пару ключ-значение с помощью ключевого слова del .

phones =
"Иван": "+7123456789",
"Василий": "+37520123456"
>
del phones["Василий"]

Вы можете сохранять контейнеры в других контейнерах. Например, можно хранить списки внутри списка.

music =
"rap": ["Баста", "Кравц", "Злой Дух"],
"rock": ["Наутилус Помпилиус", "Кино", "Ария"],
"djs": ["Paul Oakenfold", "Tiesto"]
>

В этом примере словарь music имеет три ключа, каждый из которых является списком: К этим спискам можно получить доступ с помощью соответствующих ключей

music =
"rap": ["Баста", "Кравц", "Злой Дух"],
"rock": ["Наутилус Помпилиус", "Кино", "Ария"],
"djs": ["Paul Oakenfold", "Tiesto"]
>
print(music['rap']) # ['Баста', 'Кравц', 'Злой Дух']
print(music['rock'][-1]) # Ария

Python с нуля. Освойте с Виртуальным ИИ-помощником!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *