Словарь
Списки могут быть удобны во многих ситуациях, но они ограничены тем, что к элементам обращаются через индексы: 0, 1, 2 и так далее. Если вы хотите найти какой-то элемент в списке, вам нужно либо знать его индекс, либо, в худшем случае, пройти по всему списку.
Еще одна центральная структура данных в Python — словарь. В словаре элементы индексируются ключами. Каждый ключ соответствует значению. Значения, хранящиеся в словаре, можно получать и изменять с помощью ключа.
Использование словаря
Следующий пример показывает, как работает структура данных словарь. Вот простой словарь с финского на английский:
my_dictionary = {}
my_dictionary["apina"] = "monkey"
my_dictionary["banaani"] = "banana"
my_dictionary["cembalo"] = "harpsichord"
print(len(my_dictionary))
print(my_dictionary)
print(my_dictionary["apina"])3 {'apina': 'monkey', 'banaani': 'banana', 'cembalo': 'harpsichord'} monkey
Запись {} создает пустой словарь, в который теперь можно добавить содержимое. Добавляются три пары ключ-значение: "apina" соответствует "monkey", "banaani" соответствует "banana", а "cembalo" соответствует "harpsichord". В конце выводится количество пар ключ-значение в словаре, весь словарь и значение, связанное с ключом "apina".
После определения словаря мы также могли бы использовать его с пользовательским вводом:
word = input("Please type in a word: ")
if word in my_dictionary:
print("Translation: ", my_dictionary[word])
else:
print("Word not found")Обратите внимание на использование оператора in выше. Когда он применяется к переменной типа словарь, он проверяет, находится ли первый операнд среди ключей, хранящихся в словаре. При разных вводах эта программа может вывести следующее:
Please type in a word: apina Translation: monkey
Please type in a word: pöllö Word not found
Что можно хранить в словаре?
Тип данных называется словарем, но он не обязан содержать только строки. Например, в следующем словаре ключи — строки, а значения — целые числа:
results = {}
results["Mary"] = 4
results["Alice"] = 5
results["Larry"] = 2Здесь ключи — целые числа, а значения — списки:
lists = {}
lists[5] = [1, 2, 3]
lists[42] = [5, 4, 5, 4, 5]
lists[100] = [5, 2, 3]Как работают ключи и значения
Каждый ключ может появиться в словаре только один раз. Если вы добавите запись с ключом, который уже существует в словаре, исходное значение, связанное с этим ключом, будет заменено новым значением:
my_dictionary["suuri"] = "big"
my_dictionary["suuri"] = "large"
print(my_dictionary["suuri"])large
Все ключи в словаре должны быть неизменяемыми. Поэтому список нельзя использовать как ключ, потому что его можно изменить. Например, выполнение следующего кода вызывает ошибку:
my_dictionary[[1, 2, 3]] = 5TypeError: unhashable type: 'list'
В отличие от ключей, значения, хранящиеся в словаре, могут изменяться, поэтому в качестве значения подходит любой тип данных. Одно и то же значение также может быть связано с несколькими ключами в одном словаре.
Обход словаря
Знакомый цикл for item in collection можно использовать и для обхода словаря. Если использовать его напрямую со словарем, цикл проходит по ключам, хранящимся в словаре, один за другим. В следующем примере выводятся все ключи и значения, хранящиеся в словаре:
my_dictionary = {}
my_dictionary["apina"] = "monkey"
my_dictionary["banaani"] = "banana"
my_dictionary["cembalo"] = "harpsichord"
for key in my_dictionary:
print("key:", key)
print("value:", my_dictionary[key])key: apina value: monkey key: banaani value: banana key: cembalo value: harpsichord
Иногда нужно пройти по всему содержимому словаря. Метод items возвращает все ключи и значения, хранящиеся в словаре, по одной паре за раз:
for key, value in my_dictionary.items():
print("key:", key)
print("value:", value)В примерах выше вы могли заметить, что ключи обрабатываются в том же порядке, в котором они были добавлены в словарь. Поскольку ключи обрабатываются на основе хеш-значения, порядок обычно не должен иметь значения в приложениях. На самом деле во многих старых версиях Python порядок не гарантированно соответствует времени добавления.
Несколько более продвинутых способов использовать словари
Рассмотрим список слов:
word_list = [
"banana", "milk", "beer", "cheese", "sourmilk", "juice", "sausage",
"tomato", "cucumber", "butter", "margarine", "cheese", "sausage",
"beer", "sourmilk", "sourmilk", "butter", "beer", "chocolate"
]Мы хотели бы анализировать этот список слов разными способами. Например, хотели бы знать, сколько раз каждое слово встречается в списке.
Словарь может быть полезным инструментом для управления такой информацией. В примере ниже мы проходим по элементам списка один за другим. Используя слова из списка как ключи в новом словаре, мы связываем с каждым ключом количество раз, которое слово встречалось:
def counts(my_list):
words = {}
for word in my_list:
# if the word is not yet in the dictionary, initialize the value to zero
if word not in words:
words[word] = 0
# increment the value
words[word] += 1
return words
# call the function
print(counts(word_list))Программа выводит следующее:
{'banana': 1, 'milk': 1, 'beer': 3, 'cheese': 2, 'sourmilk': 3, 'juice': 1, 'sausage': 2, 'tomato': 1, 'cucumber': 1, 'butter': 2, 'margarine': 1, 'chocolate': 1}
А что если мы хотим классифицировать слова по первой букве каждого слова? Один способ сделать это — использовать словари:
def categorize_by_initial(my_list):
groups = {}
for word in my_list:
initial = word[0]
# initialize a new list when the letter is first encountered
if initial not in groups:
groups[initial] = []
# add the word to the appropriate list
groups[initial].append(word)
return groups
groups = categorize_by_initial(word_list)
for key, value in groups.items():
print(f"words beginning with {key}:")
for word in value:
print(word)Структура функции очень похожа на предыдущее упражнение, но на этот раз значениями, связанными с ключами, являются списки. Программа выводит следующее:
words beginning with b: banana beer butter beer butter beer words beginning with m: milk margarine words beginning with c: cheese cucumber cheese chocolate words beginning with s: sourmilk sausage sausage sourmilk sourmilk words beginning with j: juice words beginning with t: tomato
Удаление ключей и значений из словаря
Разумеется, пары ключ-з начение из словаря тоже можно удалять. Есть два способа сделать это. Первый — команда del:
staff = {"Alan": "lecturer", "Emily": "professor", "David": "lecturer"}
del staff["David"]
print(staff){'Alan': 'lecturer', 'Emily': 'professor'}
Если попытаться использовать команду del для удаления ключа, которого нет в словаре, возникнет ошибка:
staff = {"Alan": "lecturer", "Emily": "professor", "David": "lecturer"}
del staff["Paul"]>>> del staff["Paul"] Traceback (most recent call last): File "", line 1, in KeyError: 'Paul'
Поэтому перед удалением ключа нужно проверить, присутствует ли он в словаре:
staff = {"Alan": "lecturer", "Emily": "professor", "David": "lecturer"}
if "Paul" in staff:
del staff["Paul"]
print("Deleted")
else:
print("This person is not a staff member")Другой способ удалять записи из словаря — метод pop:
staff = {"Alan": "lecturer", "Emily": "professor", "David": "lecturer"}
deleted = staff.pop("David")
print(staff)
print(deleted, "deleted"){'Alan': 'lecturer', 'Emily': 'professor'} lecturer deleted
Как видно выше, pop также возвращает значение из удаленной записи.
По умолчанию pop тоже вызывает ошибку, если попытаться удалить ключ, которого нет в словаре. Этого можно избежать, передав методу второй аргумент, который содержит значение возврата по умолчанию. Это значение возвращается, если ключ не найден в словаре. Здесь подойдет специальное значение Python None:
staff = {"Alan": "lecturer", "Emily": "professor", "David": "lecturer"}
deleted = staff.pop("Paul", None)
if deleted == None:
print("This person is not a staff member")
else:
print(deleted, "deleted")This person is not a staff member
Обратите внимание: если вам нужно удалить содержимое всего словаря и вы попытаетесь сделать это циклом for, например так
staff = {"Alan": "lecturer", "Emily": "professor", "David": "lecturer"}
for key in staff:
del staff[key]вы получите сообщение об ошибке:
RuntimeError: dictionary changed size during iteration
При обходе коллекции циклом for ее содержимое не должно изменяться во время выполнения цикла.
К счастью, для этой цели есть метод словаря:
staff.clear()Использование словарей для структурированных данных
Словари очень полезны для структурирования данных. Следующий код создаст словарь, содержащий некоторые персональные данные:
person = {"name": "Pippa Python", "height": 154, "weight": 61, "age": 44}Это означает, что у нас есть человек по имени Pippa Python, рост которого 154, вес 61 и возраст 44. Ту же информацию можно было бы хранить в переменных:
name = "Pippa Python"
height = 154
weight = 61
age = 44Преимущество словаря в том, что это коллекция. Он собирает связанные данные в одной переменной, поэтому легко получать доступ к разным компонентам. Такое же преимущество дает список:
person = ["Pippa Python", 153, 61, 44]При использовании списков программист должен помнить, что хранится по каждому индексу списка. Ничто не указывает, что person[2] содержит вес, а person[3] — возраст человека. При использовании словаря этой проблемы нет, потому что к каждому фрагменту данных обращаются через именованный ключ.
Предположим, мы определили нескольких людей в одном и том же формате. Тогда мы можем получить доступ к их данным следующим образом:
person1 = {"name": "Pippa Python", "height": 154, "weight": 61, "age": 44}
person2 = {"name": "Peter Pythons", "height": 174, "weight": 103, "age": 31}
person3 = {"name": "Pedro Python", "height": 191, "weight": 71, "age": 14}
people = [person1, person2, person3]
for person in people:
print(person["name"])
combined_height = 0
for person in people:
combined_height += person["height"]
print("The average height is", combined_height / len(people))Pippa Python Peter Pythons Pedro Python The average height is 173.0
На этом этапе курса вы можете выбрать участие в исследовании, связанном с обучением программированию. Участие добровольное, и отдельных участников нельзя будет идентифицировать по данным, собранным в исследовании. Вы можете свободно выйти из эксперимента в любой момент. Нажмите здесь, чтобы начать исследование!
Текущие баллы можно посмотреть в синем индикаторе в правом нижнем углу страницы.