Лутц М. - Изучаем Python (1077325), страница 28
Текст из файла (страница 28)
Главная цель этого краткого обзора состоит в том, чтобы проиллюстрировать наличие как простых, так и очень сложных инструментов в арсенале РуФЬоп. Генераторы списков можно и не использовать, но на практике они оказываются очень удобными и нередко обеспечивают более высокую производительность при работе со списками. Кроме того, их можно применять к любым другим последовательностям в языке Руб)топ, а также к некоторым другим типам, которые не являются последовательностями. Мы еще будем говорить об этих выражениях далее, в этой книге. Словари Словари в языке Рус)гоп — это нечто совсем иное (по выражению Монти Пайтона), они вообще не являются последовательностями, это то, что известно, как отображения. Отображения — это коллекции объектов, 1гВ Глава 4. Введение в типы объектов языка Руйзоп но доступ к ним осуществляется не по определенным смещениям от начала коллекции, а по ключам.
В действительности отображения вообще не подразумевают какого-либо упорядочения элементов по их позиции, они просто отображают ключи на связанные с ними значения. Словари — единственный тип отображения в наборе базовых объектов Ру()топ — также относятся к классу изменяемых объектов: они могут изменяться непосредственно, и в случае необходимости могут увеличиваться и уменьшаться в размерах, подобно спискам. Операции отображения Когда словарь определяется как литерал, программный код определения заключается в фигурные скобки и состоит из последовательности пар «ключ: значение». Словари удобно использовать всегда, когда возникает необходимость связать значения с ключами, например чтобы описать свойства чего-либо.
В качестве примера рассмотрим следующий словарь, состоящий из трех элементов (с ключами «(оог(» (продукт питания), «с(папФ((у» (количество) и «со!ог» (цвет)): »> 0 = ('тооб': 'Враз', 'Ооаптзту': 4, 'со1ог': 'р1па') Мы можем обращаться к элементам этого словаря по ключам и изменять значения, связанные с ключами. Для доступа к элементам словаря используется тот же синтаксис, который используется для обращения к элементам последовательностей, только в квадратных скобках указывается не смещение относительно начала последовательности, а ключ: В Получить значение, связанное с ключон 'Гооб' »> О('тооб'1 'Враз' »> О['ооаптыу') »= т в прибавить ) к значению ключе 'совлгзту' »> 0 ('тооб'. 'Враз', 'со1ог': 'ртпи', 'Оопп(>ту'. 5) »>0 () »> О('папе'] = 'Воь' »> О(')оЬ'1 = 'беч' »> О('аде' 1 = 40 в В результате присваивания создается ключ »> 0 ('аде' 40, ')оЬ': 'беч', 'папе'; 'ВоЬ') »> рг1пт О('папе'1 ВоЬ Несмотря на то что форма определения словаря в виде литерала, заключенного в фигурные скобки, достаточно наглядна, на практике чаще встречаются другие способы создания словарей.
Следующий пример начинается с создания пустого словаря, который затем заполняется по одному ключу за раз. В отличие от списков, не допускающих присваивания значений отсутствующим элементам, присваивание значения по несуществующему ключу в словаре приводит к созданию этого ключа: 129 Словари В этом примере ключи словаря играют роль имен полей в записи, которая описывает некоторого человека.
В других приложениях словари могут использоваться для замены операций поиска, поскольку обращение к элементу словаря по ключу обычно выполняется быстрее, чем поиск, реализованный на языке Ру[Ъоп. Еще раз о вложенности »> гес = слаще'; ('«[гас': 'Воь', '1авт': 'Ва1ть'), ')оо'; ['беч', 'аог'], 'аое': 40.5) Здесь мы опять имеем словарь, содержащий три ключа верхнего уровня (ключи «паше» (имя), «)оЪ» (должность) и «аяе» (возраст)), однако значения имеют более сложную структуру: для описания имени человека используется вложенный словарь, чтобы обеспечить поддержку имен, состоящих из нескольких частей, и для перечисления занимаемых должностей используется вложенный список, что обеспечит возможность расширения в будущем. К компонентам этой структуры можно обращаться почти так же, как мы делали это в случае с матрицей, но на этот раз вместо числовых индексов мы используем ключи словаря: »> тес['паае'] Лэшв - это вломеннвй словэр» С1авь 'Баыс', 'Гггэт .
'ВоЬ ) »> тес['лаве'К'1аат') э Обращение к элементу вло»энного словаря 'ватто ' В 'чоб' - это вломенний список »> гас[')ЬЬ') ['беч, 'а9г'] »> гас[')ЬЬ')[-1] 'аог' Э Обращение к элементу вломенного слискэ »> гас[')оь'].арреоб(')ао1«ог') в Расширение списка долкноствй Боба [Ооо) »> тес Расе': 40.5, ')оь' ['беч', 'асг', ')ао1гог'], 'паше': с1авг': 'Ва)ть', 'гтгэт': 'ВоЬ')) Обратите внимание, как последняя операция в этом примере выполняет расширение вложенного списка.
Так как список должностей — это отдельный от словаря участок в памяти, он может увеличиваться и уменьшаться без каких-либо ограничений (размещение объектов в памяти будет обсуждаться позже, в этой же книге). В предыдущем примере словарь использовался для описания гипотетической персоны с помощью трех ключей. Теперь предположим, что информация имеет более сложную структуру. Возможно, придется записать имя и фамилию, а также несколько названий должностей, занимаемых одновременно. Это приводит к необходимости использования вложенных объектов Ру[Ъоп.
Словарь в следующем примере определен в виде литерала и имеет более сложную структуру: Глава 4. Введение е типы обьектоз языка Рутлол Основная цель демонстрации этого примера состоит в том, чтобы показать вам гибкость базовых типов данных в языке РубЬоп. Здесь вы можете видеть, что возможность вложения позволяет легко воспроизводить достаточно сложные структуры данных.
Для создания подобной структуры на языке С потребовалось бы приложить больше усилий и написать больше программного кода: нам пришлось бы описать и объявить структуры и массивы, заполнить их значениями, связать их между собой и т. д. В языке Ру1Ьоп все это делается автоматически — запуск выражения приводит к созданию всей структуры вложенных объектов. Фактически, это одно из основных преимуществ языков сценариев, таких как РуФЬоп. Так же как и в низкоуровневых языках программирования, мы могли бы выполнить освобождение памяти, занимаемой объектами, которые стали не нужны. В языке РубЬоп память освобождается автоматически, когда теряется последняя ссылка на объект, например в случае присваивания переменной какого-либо другого значения: >» гес = 0 я Теперь пенять, занятая обьектон, будет осеобоядене С технической точки зрения, интерпретатор Ру1Ьоп обладает такой особенностью, как сборка мусора, благодаря которой в ходе выполнения программы производится освобождение неиспользуемой памяти, что освобождает нас от необходимости предусматривать специальные действия в программном коде.
Интерпретатор освобождает память сразу же, как только будет ликвидирована последняя ссылка на объект. С работой этого механизма мы познакомимся далее, в этой же книге, а пока достаточно знать, что вы можете работать с объектами, не беспокоясь о выделении или освобождении памяти для них.' Сортировка по ключам: циклы Фог Будучи отображениями, как мы уже видели, словари поддерживают доступ к элементам только по ключам.
Однако они кроме того поддерживают ряд специфических для данного типа операций, реализованных в виде методов, которые удобно использовать в разных случаях. Как уже упоминалось ранее„из-за того, что словари не являются последовательностями, они не предусматривают какой-либо надежный способ упорядочения позиций элементов.
Это означает, что если мы создадим словарь и попытаемся вывести его, порядок следования ключей при выводе может не совпадать с порядком, в каком они определялись: В качестве примечания: имейте в виду, что запись гес, которую мы создали здесь, в действнтельностн может быть записью е базе данных, если бы мы использовали систему хранения объектов РуСЬоп — простейший способ хранения объектов РуСЬоц в файлах илв в базах данных, обеспечивающих доступ по ключу. Мы не будем здесь углубляться е подробности, а эа дополнительной информацией по этому вопросу обращайтесь к модулям РуСЬоп— Ото к1е н эпе1се.
Словари »> 0 = ('а'. 1, 'Ь': 2, 'с': 3) »> 0 ('а К 'с . 3, 'Ь': 2) Как же быть, если нам действительно потребуется упорядочить элементы словаря7 В наиболее общем случае мы могли бы получить список всех ключей словаря методом Кеув, отсортировать их с помощью метода списка вог1 и затем выполнить обход значений в цикле гог: »> Кв = О,аеув() № Неупорлдоченний список ключей »> Ка ['а', 'с', 'Ь'] »> Кв.
вог1() № Оортировка списка ключей »> Кв ['а', 'ь', 'с'] »> гог кеу 1п кв: № Обход отсортированного списка ключей рг1пь Кеу, '=>', О[кеу] а => 1 Ь => 2 с => 3 Этот процесс, состоящий из трех этапов, в последних версиях Ру1)1оп можно упростить до единственной операции, как будет показано в последующих главах, с помощью новой встроенной функции вогьеб (функция вогьеб сортирует объекты разных типов и возвращает их): »> 0 ('а': 1, 'с'; 3, 'Ь': 2) >» Гог Кеу 1п вогьвс(0): рг1пь Кеу, '=>', О[ Кеу] а=>1 Ь => 2 с => 3 Этот пример может служить поводом для знакомства с циклом (ог языка Ру1)гоп.