Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 69
Текст из файла (страница 69)
При определении в виде литералов словари записываютсякак последовательность пар key:value, разделенных запятыми, заключенныхв фигурные скобки.1 Пустой словарь в литеральном представлении – это пустая пара скобок. Словари могут вкладываться в литеральном представлениив виде значений внутри других словарей, списков или кортежей.1Как и в случае со списками, вам нечасто придется встречать словари, сконструированные с использованием литералов.
Однако списки и словари увеличиваются в размерах по-разному. Как будет показано в следующем разделе, словари обычно дополняются с помощью операции присваивания по новым ключам во время выполненияпрограммы – такой подход совершенно не годится для списков (списки обычно расширяются с помощью метода append).266Глава 8. Списки и словариТаблица 8.2. Литералы словарей и операцииОперацияИнтерпретацияD = {}Пустой словарьD = {‘spam’: 2, ‘eggs’: 3}Словарь из двух элементовD = {‘food’: {‘ham’: 1, ‘egg’: 2}}ВложениеD = dict(name=’Bob’, age=40)Альтернативные способы созданиясловарей:D = dict(zip(keyslist, valslist))D = dict.fromkeys([‘a’, ‘b’])именованные аргументы, применениефункции zip, списки ключейD[‘eggs’]Доступ к элементу по ключуD[‘food’][‘ham’]‘eggs’ in DПроверка на вхождение: проверка наличия ключаD.keys()Методы: список ключей,D.values()список значений,D.items()список ключей и значений,D.copy()копирование,D.get(key, default)получение значения по умолчанию,D.update(D2)слияние,D.pop(key)удаление и так далееlen(D)Длина (количество элементов)D[key] = 42del D[key]Добавление/изменение ключей,удаление ключейlist(D.keys())Представления словарей (в Python 3.0)D1.keys() & D2.keys()D = {x: x*2 for x in range(10)}Генераторы словарей (в Python 3.0)Словари в действииСогласно табл. 8.2, доступ к элементам словарей осуществляется по ключу,а для доступа к элементам вложенных словарей осуществляется путем объединения серии индексов (ключей в квадратных скобках) в цепочку.
Когдаинтерпретатор создает словарь, он сохраняет элементы в произвольном порядке – чтобы получить значение обратно, необходимо указать ключ, с которымэто значение было ассоциировано. Давайте вернемся в интерактивный сеансработы с интерпретатором и исследуем некоторые операции над словарями изтабл. 8.2.267Словари в действииБазовые операции над словарямиВ обычном случае сначала создается словарь, а затем выполняются операциисохранения новых ключей и обращения к элементам по ключу:% python>>> D = {‘spam’: 2, ‘ham’: 1, ‘eggs’: 3} # Создание словаря>>> D[‘spam’]# Извлечение значения по ключу2>>> D# Случайный порядок следования{‘eggs’: 3, ‘ham’: 1, ‘spam’: 2}Здесь переменной D присваивается словарь, в котором ключу ‘spam’ соответствует целочисленное значение 2, и так далее.
Для доступа к элементам словаря используется тот же самый синтаксис с квадратными скобками, что и приизвлечении элементов списков, но в данном случае доступ осуществляется поключу, а не по позиции элемента.Обратите внимание на последнюю инструкцию в этом примере: порядок следования ключей в словаре практически всегда отличается от первоначального. Дело в том, что для обеспечения максимально высокой скорости поискапо ключу (для хеширования) ключи должны располагаться в памяти в иномпорядке. Именно поэтому операции, которые предполагают наличие установленного порядка следования элементов слева направо (например, извлечениесреза, конкатенация), неприменимы к словарям – они позволяют извлекатьзначения только по ключам, а не по индексам.Встроенная функция len может работать и со словарями – она возвращает число элементов в словаре или, что то же самое, длину списка ключей.
Операторin проверки вхождения позволяет проверить наличие ключа, а метод keys возвращает все ключи, имеющиеся в словаре, в виде списка. Последний удобно использовать для последовательной обработки словарей, но при этом вы не должны делать какие-либо предположения о порядке следования ключей в списке.Поскольку результатом вызова метода keys является список, он всегда можетбыть отсортирован (ниже мы подробнее коснемся проблемы сортировки словарей):>>> len(D)3>>> ‘ham’ in DTrue>>> list(D.keys())[‘eggs’, ‘ham’, ‘spam’]# Число элементов словаря# Проверка на вхождение# Создает новый список ключейОбратите внимание на второе выражение в этом листинге. Как уже упоминалось ранее, оператор проверки на вхождение in может использоваться для работы со строками и списками, но точно так же он может использоваться и дляработы со словарями.
Это возможно благодаря тому, что словари определяютитераторы, которые обеспечивают пошаговый обход списков ключей. Существуют и другие типы, которые поддерживают итераторы, отвечающие обычному использованию типа; например, файлы имеют итераторы, которые позволяют выполнять построчное чтение данных. Итераторы будут рассматриватьсяв главах 14 и 20.268Глава 8. Списки и словариОбратите также внимание на синтаксис последнего примера в листинге.
В версии Python 3.0 мы были вынуждены заключить вызов метода в вызов функцииlist по уже встречавшейся ранее причине – в версии 3.0 метод keys возвращает итератор, а не список. Вызов функции list принудительно выполняет обходвсех значений итератора, что позволяет вывести их все сразу. В версии 2.6 метод keys конструирует и возвращает обычный список, поэтому для отображения результатов вызов функции list в этой версии интерпретатора не требуется. Подробнее об этом рассказывается ниже, в этой главе.Ключи в словарях следуют в произвольном порядке, которыйможет изменяться от версии к версии, поэтому не нужно тревожиться, если у вас ключи будут выведены в порядке, отличномот того, что приводится здесь. В действительности порядок следования ключей изменился и у меня – я выполнял все эти примеры под управлением Python 3.0, и порядок следования ключей изменился по сравнению с тем, что приводился в примерахв предыдущем издании.
Вы не должны полагаться на какой-тоопределенный порядок следования ключей ни в своих программах, ни при чтении книг!Изменение словарейДавайте продолжим работу в интерактивном сеансе. Словари, как и списки,относятся к категории изменяемых объектов, поэтому их можно изменять,увеличивать, уменьшать непосредственно, не создавая новые словари: чтобыизменить или создать новую запись в словаре, достаточно выполнить операциюприсваивания по ключу.
Инструкция del также может применяться к словарям – она удаляет значение, связанное с ключом, который играет роль индекса. Кроме того, обратите внимание на наличие вложенного списка в следующем примере (значение для ключа ‘ham’). Все типы-коллекции в языке Pythonмогут вкладываться друг в друга в произвольном порядке:>>> D{‘eggs’: 3, ‘ham’: 1, ‘spam’: 2}>>> D[‘ham’] = [‘grill’, ‘bake’, ‘fry’] # Изменение элемента>>> D{‘eggs’: 3, ‘ham’: [‘grill’, ‘bake’, ‘fry’], ‘spam’: 2}>>> del D[‘eggs’]# Удаление элемента>>> D{‘ham’: [‘grill’, ‘bake’, ‘fry’], ‘spam’: 2}>>> D[‘brunch’] = ‘Bacon’# Добавление нового элемента>>> D{‘brunch’: ‘Bacon’, ‘ham’: [‘grill’, ‘bake’, ‘fry’] , ‘spam’: 2}Как и в случае со списками, операция присваивания по существующему ключу словаря приводит к изменению ассоциированного с ним значения.
Однаков отличие от списков, словари допускают выполнение присваивания по новому ключу (который ранее отсутствовал), в результате создается новый элементсловаря, как показано в предыдущем примере для ключа ‘brunch’. Этот при-269Словари в действиием не может применяться к спискам, потому что в этом случае интерпретаторобнаруживает выход за пределы списка и генерирует сообщение об ошибке.Чтобы увеличить размер списка, необходимо использовать такие инструментысписков, как метод append или присваивание срезу.Дополнительные методы словарейМетоды словарей обеспечивают выполнение различных операций. Например,методы словарей values и items возвращают список значений элементов словаряи кортежи пар (key, value) соответственно:>>> D = {‘spam’: 2, ‘ham’: 1, ‘eggs’: 3}>>> list(D.values())[3, 1, 2]>>> list(D.items())[(‘eggs’, 3), (‘ham’, 1), (‘spam’, 2)]Такие списки удобно использовать в циклах, когда необходимо выполнить обход элементов словаря.
Попытка извлечения несуществующего элемента словаря обычно приводит к появлению ошибки, однако метод get в таких случаяхвозвращает значение по умолчанию (None или указанное значение). С помощьюэтого метода легко можно реализовать получение значений по умолчанию и избежать появления ошибки обращения к несуществующему ключу:>>> D.get(‘spam’)2>>> print(D.get(‘toast’))None>>> D.get(‘toast’, 88)88# Ключ присутствует в словаре# Ключ отсутствует в словареМетод update реализует своего рода операцию конкатенации для словарей, приэтом он не имеет никакого отношения к упорядочению элементов слева направо (для словарей такое упорядочение не имеет смысла).
Он объединяет ключии значения одного словаря с ключами и значениями другого, просто перезаписывая значения с одинаковыми ключами:>>> D{‘eggs’: 3, ‘ham’: 1, ‘spam’: 2}>>> D2 = {‘toast’:4, ‘muffin’:5}>>> D.update(D2)>>> D{‘toast’: 4, ‘muffin’: 5, ‘eggs’: 3, ‘ham’: 1, ‘spam’: 2}Наконец, метод pop удаляет ключ из словаря и возвращает его значение. Он напоминает метод pop списков, только вместо необязательного индекса элементапринимает ключ:# удаление элементов словаря по ключу>>> D{‘toast’: 4, ‘muffin’: 5, ‘eggs’: 3, ‘ham’: 1, ‘spam’: 2}>>> D.pop(‘muffin’)5>>> D.pop(‘toast’)# Удаляет и возвращает значение заданного ключа4270Глава 8. Списки и словари>>> D{‘eggs’: 3, ‘ham’: 1, ‘spam’: 2}# удаление элементов списка по номеру позиции>>> L = [‘aa’, ‘bb’, ‘cc’, ‘dd’]>>> L.pop()# Удаляет и возвращает последний элемент списка‘dd’>>> L[‘aa’, ‘bb’, ‘cc’]>>> L.pop(1)# Удаляет и возвращает элемент из заданной позиции‘bb’>>> L[‘aa’, ‘cc’]Кроме того, словари имеют метод copy, который мы рассмотрим в главе 9, какодин из способов избежать побочных эффектов, связанных с наличием нескольких ссылок на один и тот же словарь.
В действительности словари обладают гораздо большим числом методов, чем перечислено в табл. 8.2. Чтобы получить полный список, обращайтесь к руководствам по языку PythonТаблица языковДавайте рассмотрим более жизненный пример словаря. В следующем примересоздается таблица, которая отображает названия языков программирования(ключи) на имена их создателей (значения).