Саммерфилд - Программирование на Python 3 (1077331), страница 28
Текст из файла (страница 28)
Типы коллекций В предыдущей главе мы познакомились с наиболее важными фундаментальными типами данных языка Рубанов. В этой главе мы расширим свои возможности, узнав, как объединять элементы данных вместе, используя типы коллекций языка Руьноп. В этой главе мы рассмотрим кортежи и списки, а также познакомимся с новыми типами коллекций, включая словари и множества, и детально изучим их.' В дополнение к коллекциям мы также узнаем, как создавать элементы данных, вмещающие в себя другие элементы данных (подобно структурам в языках С и С++ и записям в языке Рааса)).
Такие элементы в случае необходимости могут интерпретироваться как единое целое, и при этом сохраняется возможность прямого доступа к отдельным элементам, хранящимся в них. Естественно, ничто не мешает вставлять такие агрегатные элементы в коллекции, как любые другие алементы. Наличие коллекций элементов данных существенно упрощает выполнение операций, которые должны применяться к элементам, а также упрощает обработку коллекций элементов при чтении их из файлов.
В этой главе мы рассмотрим основные приемы работы с файлами лишь в том объеме, который нам потребуется, отложив описание основных подробностей (включая обработку ошибок) до главы 7. После знакомства с отдельными типами коллекций мы посмотрим, как можно организовать обход коллекций в цикле, поскольку в языке Ру$Ьоп для итераций через любые коллекции используются одни и те же синтаксические конструкции. Кроме этого„мы исследуем проблемы и приемы копирования коллекций. Определение того, что является последовательностью, множеством или отображением, в этой главе дается не с формальной, а с практической точки зрения. Более формальные определения даются в главе 8. Глаза 3.
Типы коллекций Последовательности Кортежи а Извлвнвннв срезов из строк, стр. 89 Кортеж — это упорядоченная последовательность из нуля или более ссылок на объекты. Кортежи поддерживают тот же синтаксис получения срезов, что и строки. Зто упрощает извлечение элементов из кортежа. Подобно строкам, кортежи относятся к категории неизменяемых объектов, поэтому мы не можем замещать или удалять какие-либо их элементы.
Если нам необходимо иметь возможность изменять упорядоченную последовательность, то вместо кортежей можно просто использовать списки или, если в программе уже используется кортеж, который нежелательно модифицировать, можно преобразовать кортеж в список с помощью функции преобразования 1тзс( ) и затем изменять полученный список. Тип данных сор1е может вызываться как функция тор1е() — без аргументов она возвращает пустой кортеж, с аргументом типа сор1е возвращает поверхностную копию аргумента; в случае, если аргумент имеет другой тип, выполняется попытка преобразовать его в объект типа сор1е. Зта функция принимает не более одного аргумента. Кроме того, кортежи могут создаваться без использования функции сор1е( ).
Пустой кортеж создается с помощью пары пустых круглых скобок (), а кортеж, состоящий из одного или более элементов, может быть создан с помощью запятых. Иногда кортежи приходится заключать в круглые скобки, чтобы избежать синтаксической неоднозначности. Например, чтобы передать кортеж 1, 2, 3 в функцию, необходимо использовать такуюформузаписи: ГолсгтспП1, 2, 3)). Последовательности — это один из типов данных, поддерживающих оператор проверки на вхождение (1п), функцию определения размера (1еп()), оператор извлечения срезов (с)) и возможность выполнения итераций.
В языке РуФ)топ имеется пять встроенных типов последовательностей: Ьутеаггау, Ьутез, 1ззт, зсг и тор1е — первые два будут описаны отдельно, в главе 7. Ряд дополнительных типов последовательностей реализован в стандартной библиотеке; наиболее примечательным из них является тип со11есттолз. пазеотор1е. При выполнении итераций все эти последовательности гарантируют строго определенный порядок следования элементов.
о Строки мы уже рассматривали в предыдущей главе, а в этом разделе познакомимся с кортежами, именованными кортежами и списками. Последовательности Рис. 3.1. Позиции элементов в кортеже Нарис. 3.1 показан кортеж[ = "уепиа", -28, "0гееп", "21", 19.74 и индексы элементов внутри кортежа. Строки индексируются точно так же, но, если в строках каждой позиции соответствует единственный символ, то в кортежах каждой позиции соответствует единственная ссылка на объект. Кортежи предоставляют всего два метода: т, соипс(х), который возвращает количество объектов х в кортеже ц и т.
тпоех(х), который возвращает индекс самого первого (слева) вхождения объекта х в кортеж т или возбуждает исключение На)иеЕггог, если объект х отсутствует в кортеже. (Эти методы имеются также и у списков.) Кроме того, кортежи могут использоваться с оператором е (конкатенации), * (дублирования) и [] (получения среза), а операторы то и пот тп могут применяться для проверки на вхождение.
Можно использовать также комбинированные операторы присваивания += и *=. Несмотря на то, что кортежи являются неизменяемыми объектами, при выполнении этих операторов интерпретатор РуФ]топ создает за кулисами новый кортеж с результатом операции и присваивает ссылку на него объекту, расположенному слева от оператора, то есть используется тот же самый прием, что и со строками. Кортежи могут сравниваться с помощью стандартных операторов сравнения («, =, ==,! =, »=, ), при этом сравнивание производится поэлементно (и рекурсивно, при наличии вложенных элементов, таких как кортежи в кортежах).
Рассмотрим несколько примеров получения срезов, начав с извлечения единственного элемента и группы элементов: »> па1г = "ыасх", "ьгпип", "ыопсе", "геп" »> лагг[2] 'Ыопое' »> патг[-3:] Ф то же, чтп и па[г[1:] ('Ьгоип', 'Ыпппе', 'геа') Эта операция выполняется точно так же, как и в случае со строками, списками или любыми другими последовательностями. »> патг[:2], "Ьгау", лагг[2:] [('Ыаса', 'огонь'), 'Згау', ('Ысппе', 'геп')) Здесь мы попытались создать новый кортеж из 5 элементов, но в результате получили кортеж с тремя элементами, содержащий два двух- Глава 3. Типы коллекций элементных кортежа. Это произошло потому, что мы применили опе- ратор запятой к трем элементам (кортеж, строка и кортеж). Чтобы по- лучить единый кортеж со всеми этими элементами, необходимо вы- полнить конкатенацию кортежей: »> па1г[:2) + ("дгау",) а па!г[2:] ('Ыаск', 'Ьгомп', 'дгау', 'Ыопсе', 'гес') Чтобы создать кортеж из одного элемента, необходимо поставить запятую, но если запятую просто добавить, будет получено исключение ТуреБггог (так как интерпретатор будет думать, что выполняется конкатенация строки и кортежа), поэтому необходимо использовать запятую и круглые скобки.
В этой книге (начиная с этого момента) мы будем использовать определенный стиль записи кортежей. Когда кортеж будет стоять слева от двухместного оператора или справа от одноместного, мы будем опускать круглые скобки. Во всех остальных случаях будут использоваться круглые скобки. Ниже приводятся несколько примеров: а, Ь=(1,2) Ое! а, Ь а слева от двухместного оператора а справа от одноместного оператора оег т(х).
гетогп х, х * ° 2 в справа от одноместного оператора гог х, у тп ((1, 1), (2, 4), (3, 9)): и слева от двухместного оператора ргапт(х, у) Совершенно необязательно следовать этому стилю записи — некоторые программисты предпочитают всегда использовать круглые скобки, что соответствует репрезентативной форме представления кортежей, одна- ко другие используют скобки, только когда это строго необходимо. »> еуеа = ("Ьгомп", 'Паге1", "апЬег", "дгееп", "Ыое", "дгау") »> со1огв = (Патг, еуев) »> со1ога[1][3:-1) ('дгееп', 'Ь1ое') »> тыпдв = (1, -7.5, ("реа", (5, "Хуа"), "Повсе")) »> татарв[2][1][1][2] а Рассмотрим этот пример по частям, начиная с выражения (Мпдв[2], которое дает нам третий элемент кортежа (не забывайте, что первый элемент имеет индекс О), который сам является кортежем ("реа", (5, "Хуа" ), "соеое" ). Выражение галде[2][1] дает нам второй элемент кор- В следующем примере мы вложили друг в друга два кортежа.
Коллекции допускают возможность вложения с любой глубиной вложенности. Оператор извлечения срезов [] может применяться для доступа к вложенным коллекциям столько раз, сколько это будет необходимо. Например: Последовательности тежа Тлтпрв(2], который тоже является кортежем (5, "Хуа" ). А выражение ТЬ Тор в [2](1](1] дает нам второй элемент этого кортежа, который представляет строку "Хуа".
Наконец, выражение ТЬ1прв(2](1](1](2] дает нам третий элемент (символ) строки, то есть символ "а". Кортежи могут хранить элементы любых типов, включая другие коллекции, такие как кортежи и списки, так как на самом деле кортежи хранят ссылки на объекты. Использование сложных, вложенных структур данных, таких, как показано ниже, легко может создавать путаницу. Одно из решений этой проблемы состоит в том, чтобы давать значениям индексов осмысленные имена. Например: »> МАМОЕАСТНЯЕМ, МООЕЦ ОЕАТТМО = (О, 1, 2) »> МТМ1МОМ, МАХТМОМ = (О, 1) »> атгсгатт = ("А)гвьв", "А820-200", (100, 220)) »> атгсгатт(БЕАТТМО](МАХ!МОМ] 220 Конечно, в таком виде программный код выглядит более осмысленным, чем простое выражение а(гсгаут(2](1], но при этом приходится создавать большое число переменных, да и выглядит он несколько уродливо.
В следующем подразделе мы познакомимся с более привлекательной альтернативой. В первых двух строках вышеприведенного фрагмента мы выполнили присваивание кортежам. Когда справа от оператора присваивания указывается последовательность (в данном случае — это кортежи), а слева указан кортеж, мы говорим, что последовательность справа распаковывается). Операция распаковывания последовательностей может использоваться для организации обмена значений между переменными, например: а, Ь=(Ь,а) Строго говоря, круглые скобки справа не являются обязательными, но, как уже отмечалось выше, в этой книге мы используем стиль записи, когда скобки опускаются только в левом операнде двухместного оператора и в правом операнде одноместного оператора и используются во всех остальных случаях.
Мы уже сталкивались с примерами распаковывания последовательностей в контексте оператора цикла Тог ... 1п. Следующий пример приводится только в качестве напоминания: Гьг х, у тп ((-3, 4), (5, 12), (28, -45)).' ргтпт(вата.пурот(х, у)) Здесь выполняется обход кортежа, состоящего из двухэлементных кортежей, каждый из которых распаковывается в переменные х и у. Глава 3. Типы коллекций Именованные кортежи Именованные кортежи ведут себя точно так же, как и обычные кортежи, и не уступают им в производительности.