Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 49
Текст из файла (страница 49)
Допустим, что переменные x и y сохранили свои значения, присвоенные в предыдущем примереинтерактивного сеанса:>>> z = x.intersection(y)>>> zset([‘b’, ‘d’])>>> z.add(‘SPAM’)>>> z# То же, что и выражение x & y# Добавит один элементДругие числовые типы185set([‘b’, ‘d’, ‘SPAM’])>>> z.update(set([‘X’, ‘Y’])) # Объединение множеств>>> zset([‘Y’, ‘X’, ‘b’, ‘d’, ‘SPAM’])>>> z.remove(‘b’)# Удалит один элемент>>> zset([‘Y’, ‘X’, ‘d’, ‘SPAM’])Будучи итерируемыми контейнерами, множества могут передаваться функции len, использоваться в циклах for и в генераторах списков. Однако так какмножества являются неупорядоченными коллекциями, они не поддерживаютоперации над последовательностями, такие как индексирование и извлечениесреза:>>> for item in set(‘abc’): print(item * 3)...aaacccbbbНаконец, операторы выражений, которые были продемонстрированы выше,обычно применяются к двум множествам, однако родственные им методы часто способны работать с любыми объектами итерируемых типов:>>> S = set([1, 2, 3])>>> S | set([3, 4])# Операторы выражений требуют,set([1, 2, 3, 4])# чтобы оба операнда были множествами>>> S | [3, 4]TypeError: unsupported operand type(s) for |: ‘set’ and ‘list’>>> S.union([3, 4])# Но их методы способны приниматьset([1, 2, 3, 4])# любые итерируемые объекты>>> S.intersection((1, 3, 5))set([1, 3])>>> S.issubset(range(-5, 5))TrueЗа дополнительной информацией по множествам обращайтесь к руководствупо стандартной библиотеке языка Python или к справочной литературе.
Хотяоперации над множествами в языке Python можно реализовать вручную, применяя другие типы данных, такие как списки и словари (часто так и делалосьв прошлом), встроенные операции над множествами обеспечивают высокуюскорость выполнения стандартных операций, опираясь на эффективные алгоритмы и приемы реализации.Литералы множеств в Python 3.0Если вы уже были знакомы с множествами и считали их отличным инструментом, то теперь они стали еще лучше.
В ��������������������������������������Python�������������������������������� 3.0 сохранилась возможность использовать встроенную функцию set для создания объектов множеств, но приэтом появилась новая форма литералов множеств, в которых используютсяфигурные скобки, прежде зарезервированные для литералов словарей. В версии 3.0 следующие инструкции являются эквивалентными:set([1, 2, 3, 4]) # Вызов встроенной функции{1, 2, 3, 4}# Литерал множества в версии 3.0186Глава 5.
ЧислаТакой синтаксис приобретает определенный смысл, если рассматривать множества как словари, в которых ключи не имеют соответствующих им значений.А поскольку множества являются неупорядоченными коллекциями уникальных и неизменяемых объектов, элементы множеств близко напоминают ключисловарей. Сходство становится еще более явным, если учесть, что в версии 3.0списки ключей в словарях являются объектами представлений, поддерживающими такие операции над множествами, как пересечение и объединение (подробнее об объектах представлений словарей рассказывается в главе 8).Независимо от того, каким способом были созданы множества, в версии 3.0они отображаются в новой форме литерала.
В версии 3.0 встроенная функцияset все еще необходима для создания пустых множеств и конструированиямножеств на основе существующих итерируемых объектов (в дополнение к генераторам множеств, о которых будет рассказываться ниже, в этой же главе),однако для создания множеств с известным содержимым удобнее использоватьновую форму литералов:C:\Misc> c:\python30\python>>> set([1, 2, 3, 4]){1, 2, 3, 4}>>> set(‘spam’){‘a’, ‘p’, ‘s’, ‘m’}>>> {1, 2, 3, 4}{1, 2, 3, 4}>>> S = {‘s’, ‘p’, ‘a’, ‘m’}>>> S.add(‘alot’)>>> S{‘a’, ‘p’, ‘s’, ‘m’, ‘alot’}# Встроенная функция: та же, что и в 2.6# Добавить все элементы итерируемого объекта# Литералы множеств: нововведение в 3.0Все операции над множествами, которые описывались в предыдущем разделе,в версии 3.0 действуют точно так же, но вывод результатов выглядит несколькоиначе:>>> S1 = {1, 2, 3, 4}>>> S1 & {1, 3}{1, 3}>>> {1, 5, 3, 6} | S1{1, 2, 3, 4, 5, 6}>>> S1 - {1, 3, 4}{2}>>> S1 > {1, 3}True# Пересечение# Объединение# Разность# НадмножествоОбратите внимание, что конструкция {} по-прежнему создает пустой словарь.Чтобы создать пустое множество, следует вызвать встроенную функцию set;результат операции вывода пустого множества выглядит несколько иначе:>>> S1 - {1, 2, 3, 4}set()>>> type({})<class ‘dict’># Пустое множество выводится иначе>>> S = set()>>> S.add(1.23)>>> S{1.23}# Инициализация пустого множества# Литерал {} обозначает пустой словарьДругие числовые типы187Как и в Python 2.6, множества, созданные с помощью литералов в версии 3.0,поддерживают те же методы, часть из которых способна принимать итерируемые объекты в качестве операндов, чего не позволяют операторы выражений:>>> {1, 2, 3} | {3, 4}{1, 2, 3, 4}>>> {1, 2, 3} | [3, 4]TypeError: unsupported operand type(s) for |: ‘set’ and ‘list’>>> {1, 2, 3}.union([3, 4]){1, 2, 3, 4}>>> {1, 2, 3}.union({3, 4}){1, 2, 3, 4}>>> {1, 2, 3}.union(set([3, 4])){1, 2, 3, 4}>>> {1, 2, 3}.intersection((1, 3, 5)){1, 3}>>> {1, 2, 3}.issubset(range(-5, 5))TrueОграничения, связанные с неизменяемостьюи фиксированные множестваМножества – это гибкие и мощные объекты, но они имеют одно ограничениев обеих версиях, 3.0 и 2.6, о котором следует помнить – из-за особенностейреализации множества могут включать объекты только неизменяемых (илитак называемых «хешируемых») типов.
Отсюда следует, что списки и словарине могут добавляться в множества, однако вы можете использовать кортежи,если появится необходимость сохранять составные значения. В операциях надмножествами кортежи сравниваются по своим полным значениям:>>> S{1.23}>>> S.add([1, 2, 3])# Добавляться могут только неизменяемые объектыTypeError: unhashable type: ‘list’>>> S.add({‘a’:1})TypeError: unhashable type: ‘dict’>>> S.add((1, 2, 3))>>> S# Ни список, ни словарь не могут быть добавлены{1.23, (1, 2, 3)}# но с кортежем таких проблем нет>>> S | {(4, 5, 6), (1, 2, 3)} # Объединение: то же, что и S.union(...){1.23, (4, 5, 6), (1, 2, 3)}>>> (1, 2, 3) in S# Членство: выявляется по полным значениямTrue>>> (1, 4, 3) in SFalseКортежи в множествах могут использоваться, например, для хранения дат,записей, IP-адресов и так далее (подробнее о кортежах рассказывается ниже,в этой же части книги).
Сами по себе множества являются изменяемыми объектами и потому не могут вкладываться в другие множества, однако, если вампотребуется сохранить одно множество внутри другого множества, создайтемножество с помощью встроенной функции frozenset, которая действует точнотак же, как функция set, но создает неизменяемое множество, которое невозможно изменить и потому можно встраивать в другие множества.188Глава 5.
ЧислаГенераторы множеств в Python 3.0Кроме литералов, в версии 3.0 появилась конструкция генератора множеств.По своему виду она напоминает конструкцию генератора списков, с котороймы предварительно познакомились в главе 4; только генератор множеств заключен не в квадратные, а в фигурные скобки, и в результате создает множество, а не список. Генератор множеств выполняет цикл и собирает результатывыражения в каждой итерации – доступ к значению в текущей итерации обеспечивает переменная цикла. Результатом работы генератора является новоемножество, обладающее всеми особенностями обычного множества:>>> {x ** 2 for x in [1, 2, 3, 4]}{16, 1, 4, 9}# Генератор множеств в 3.0Цикл, который генерирует значения, находится в этом выражении справа,а выражение, осуществляющее формирование окончательных значений, –слева (x ** 2).
Как и в случае с генераторами списков, генератор множестввозвращает именно то, что говорит: «Вернуть новое множество, содержащееквадраты значений X, для каждого X из списка». В генераторах можно такжеиспользовать другие виды итерируемых объектов, такие как строки (первыйпример в следующем листинге иллюстрирует создание множества с помощьюгенератора на основе существующего итерируемого объекта):>>> {x for x in ‘spam’}{‘a’, ‘p’, ‘s’, ‘m’}>>> {c *{‘ssss’,>>> {c *{‘ssss’,4 for c‘aaaa’,4 for c‘aaaa’,# То же, что и: set(‘spam’)in ‘spam’}# Множество результатов выражения‘pppp’, ‘mmmm’}in ‘spamham’}‘hhhh’, ‘pppp’, ‘mmmm’}>>> S = {c * 4 for c in ‘spam’}>>> S | {‘mmmm’, ‘xxxx’}{‘ssss’, ‘aaaa’, ‘pppp’, ‘mmmm’, ‘xxxx’}>>> S & {‘mmmm’, ‘xxxx’}{‘mmmm’}Поскольку для дальнейшего обсуждения генераторов необходимо знание некоторых базовых концепций, которые мы еще не рассматривали, мы отложимего до последующих глав книги.