М. Лутц - Изучаем Python (4-е издание)- 2011 (1126907), страница 68
Текст из файла (страница 68)
Как уже упоминалось ранее, оператор проверки на вхождение 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Таблица языковДавайте рассмотрим более жизненный пример словаря. В следующем примересоздается таблица, которая отображает названия языков программирования(ключи) на имена их создателей (значения). С помощью этой таблицы можно поназванию языка программирования определить имя его создателя:>>> table = {‘Python’: ‘Guido van Rossum’,...‘Perl’: ‘Larry Wall’,...‘Tcl’: ‘John Ousterhout’ }>>>>>> language = ‘Python’>>> creator = table[language]>>> creator‘Guido van Rossum’>>> for lang in table:# То же, что и: for lang in table.keys()...print(lang, ‘\t’, table[lang])...TclJohn OusterhoutPython Guido van RossumPerl Larry WallВ последней команде использован оператор цикла for, который мы еще подробно не рассматривали.
Для тех, кто не знаком с циклами for, замечу, что приведенная команда просто выполняет обход всех ключей в таблице и выводитсписок ключей и их значений, разделенных символом табуляции. Подробноо циклах for будет рассказываться в главе 13.Словари не являются последовательностями, как списки и строки, но если необходимо выполнить обход элементов словаря, в этом нет ничего сложного –это легко сделать с помощью метода keys, возвращающего все ключи словаря,которые можно обойти в цикле for. В случае необходимости внутри цикламожно получать значение элемента по его ключу, как это реализовано в данном примере.Словари в действии271Кроме того, Python в действительности позволяет выполнять обход ключейсловаря и без вызова метода keys в операторе цикла for.
Для любого словаря Dцикл можно оформить как for key in D:, что равносильно полной форме записиfor key in D.keys():. Это всего лишь еще одна разновидность итераторов, упоминавшихся ранее, которая позволяет использовать оператор проверки вхождения in со словарями (подробнее об итераторах далее в книге).Замечания по использованию словарейСловари окажутся достаточно просты в использовании, когда вы освоите работу с ними, но я хочу привести несколько соображений, которые вам следуеттвердо знать:•• Операции над последовательностями неприменимы к словарям. Словари –это отображения, а не последовательности. Вследствие того, что словари непредусматривают никакого упорядочения элементов, такие операции, какконкатенация (упорядоченное объединение) и извлечение среза (извлечениенепрерывного блока элементов), просто неприменимы. В действительности,когда в программном коде во время выполнения производится попытка сделать нечто подобное, интерпретатор выдает сообщение об ошибке.•• Присваивание по несуществующему индексу приводит к созданию новогоэлемента.
Ключи можно создавать при определении словаря в виде литерала (в этом случае они встраиваются непосредственно в литерал) или приприсваивании значения новому ключу существующего объекта словаря.Результат получается тот же самый.•• Ключи не обязательно должны быть строками. В наших примерах в качестве ключей использовались строки, но могут использоваться любые другиенеизменяемые объекты (то есть не списки).