Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 72
Текст из файла (страница 72)
Объекты представлений, возвращаемые методом values,такой особенностью не обладают, потому что они не являются уникальными,тогда как объекты представлений, возвращаемые методом items, такой особенностью обладают, если пары (key, value) являются уникальными и хешируемыми. Учитывая, что множества достаточно сильно похожи на словари, ключикоторых не имеют значений (и даже литералы множеств в версии 3.0 заключаются в фигурные скобки, как словари), это обстоятельство выглядит вполне логичным. Подобно ключам словарей, элементы множеств неупорядочены,уникальны и относятся к разряду неизменяемых объектов.Ниже наглядно показано, как интерпретируются списки ключей, когда онииспользуются в операциях над множествами. В таких операциях объектыпредставлений могут смешиваться с другими представлениями, множествамии словарями (в этом случае словари интерпретируются точно так же, как представления, возвращаемые методом keys):>>> K | {‘x’: 4}{‘a’, ‘x’, ‘c’}# Представления ключей (и иногда элементов)# похожи на множества>>> V & {‘x’: 4}TypeError: unsupported operand type(s) for &: ‘dict_values’ and ‘dict’>>> V & {‘x’: 4}.values()TypeError: unsupported operand type(s) for &: ‘dict_values’ and ‘dict_values’280Глава 8.
Списки и словари>>> D = {‘a’:1, ‘b’:2, ‘c’:3}>>> D.keys() & D.keys()# Пересечение представлений ключей{‘a’, ‘c’, ‘b’}>>> D.keys() & {‘b’}# Пересечение представления ключей и множества{‘b’}>>> D.keys() & {‘b’: 1}# Пересечение представления ключей и словаря{‘b’}>>> D.keys() | {‘b’, ‘c’, ‘d’} # Объединение представления ключей и множества{‘a’, ‘c’, ‘b’, ‘d’}Представления элементов словарей также могут обладать свойствами множеств, если они допускают возможность хеширования, – то есть, если они содержат только неизменяемые объекты:>>> D = {‘a’: 1}>>> list(D.items())# Элементы похожи на множества, если они допускают[(‘a’, 1)]# возможность хеширования>>> D.items() | D.keys() # Объединение представлений{(‘a’, 1), ‘a’}>>> D.items() | D# Словари интерпретируются как представление ключей{(‘a’, 1), ‘a’}>>> D.items() | {(‘c’, 3), (‘d’, 4)} # Множество пар ключ/значение{(‘a’, 1), (‘d’, 4), (‘c’, 3)}>>> dict(D.items() | {(‘c’, 3), (‘d’, 4)}) # Функция dict принимает также{‘a’: 1, ‘c’: 3, ‘d’: 4}# итерируемые объекты множествЗа дополнительной информацией об операциях над множествами обращайтеськ главе 5.
А теперь давайте коротко рассмотрим три другие особенности словарей, появившиеся в версии 3.0.Сортировка ключей словаряВо-первых, из-за того, что теперь метод keys не возвращает список, традиционный прием просмотра содержимого словаря по отсортированным ключам,который используется в версии 2.�������������������������������������������X������������������������������������������, непригоден в версии 3.0. Для этого необходимо либо преобразовать объект представления ключей в список, либо воспользоваться функцией sorted, представленной в главе 4 и выше в этой главе,применив ее к объекту, возвращаемому методу keys , или к самому словарю:>>> D = {‘a’:1, ‘b’:2, ‘c’:3}>>> D{‘a’: 1, ‘c’: 3, ‘b’: 2}>>> Ks = D.keys() # Сортировка объекта представления>>> Ks.sort()# не дает желаемого результата!AttributeError: ‘dict_keys’ object has no attribute ‘sort’>>> Ks = list(Ks) # Преобразовать в список и потом отсортировать>>> Ks.sort()>>> for k in Ks: print(k, D[k])...a 1b 2c 3>>> D{‘a’: 1, ‘c’: 3, ‘b’: 2}Словари в действии281>>> Ks = D.keys() # Или вызвать функцию sorted() с результатом вызова keys>>> for k in sorted(Ks): print(k, D[k]) # sorted() принимает итерируемые...# объекты и возвращает результатa 1b 2c 3>>> D{‘a’: 1, ‘c’: 3, ‘b’: 2} # Еще лучше отсортировать сам словарь>>> for k in sorted(D): print(k, D[k]) # Итератор словаря возвращает ключи...a 1b 2c 3Операция сравнения словарями больше не поддерживаетсяВо-вторых, в Python 2.6 словари могут сравниваться между собой с помощьюоператоров <, > и других, но в ��������������������������������������������Python�������������������������������������� 3.0 эта возможность больше не поддерживается.
Однако ее можно имитировать, сравнив отсортированные спискиключей вручную:sorted(D1.items()) < sorted(D2.items()) # То же, что и D1 < D2 в версии 2.6Тем не менее в версии 3.0 сохранилась возможность проверки словарей на равенство. Поскольку мы еще вернемся к этой теме в следующей главе, когда будем рассматривать операции сравнения в более широком контексте, отложимдо этого момента обсуждение деталей.Метод has_key умер, да здравствует has_key!Наконец, широко используемый метод has_key словарей, выполняющий проверку наличия ключей, был ликвидирован в версии 3.0.
Вместо него рекомендуется использовать оператор in проверки на вхождение или проверять результат вызова метода get на равенство значению по умолчанию (первый вариантпредпочтительнее):>>> D{‘a’: 1, ‘c’: 3, ‘b’: 2}>>> D.has_key(‘c’)# Только в версии 2.X: True/FalseAttributeError: ‘dict’ object has no attribute ‘has_key’>>> ‘c’ in DTrue>>> ‘x’ in DFalse>>> if ‘c’ in D: print(‘present’, D[‘c’]) # Предпочтительнее в версии 3.0...present 3>>> print(D.get(‘c’))3>>> print(D.get(‘x’))None>>> if D.get(‘c’) != None: print(‘present’, D[‘c’]) # Еще одна возможность...present 3282Глава 8.
Списки и словариЕсли вы пользуетесь версией 2.6 и вас волнует вопрос совместимости с версией 3.0, учтите, что первые два изменения (генераторы словарей и представления) доступны только в версии 3.0, а последние три (функция sorted, сравнивание вручную и оператор in) могут использоваться и в версии 2.6, что поможетоблегчить переход на версию 3.0 в будущем.В заключениеВ этой главе мы исследовали списки и словари – два, пожалуй, наиболее часто используемых, гибких и мощных типа коллекций, которые можно увидетьв программах на языке Python. Мы узнали, что списки представляют собойупорядоченные по позициям коллекции объектов произвольных типов и чтоони могут иметь неограниченное число уровней вложенности, могут увеличиваться и уменьшаться в размерах по мере необходимости и многое другое.Словари представляют похожий тип данных, но в них элементы сохраняютсяпо ключам, а не по позициям; словари не обеспечивают какой-либо надежныйспособ поддержки упорядочения элементов слева направо.
И списки, и словариотносятся к категории изменяемых объектов и поэтому поддерживают различные операции непосредственного их изменения, недоступные для строк, например списки можно увеличивать в размерах с помощью метода append, а словари – за счет выполнения операции присваивания по новому ключу.В следующей главе мы закончим подробное исследование базовых типов объектов, рассмотрев кортежи и файлы. После этого мы перейдем к инструкциям, которые реализуют логику обработки этих объектов, что позволит нам ещебольше приблизиться к написанию полноценных программ.
Но прежде чем заняться этими темами, ответьте на контрольные вопросы главы.Закрепление пройденногоКонтрольные вопросы1. Назовите два способа создания списка, содержащего пять целочисленныхзначений, равных нулю.2. Назовите два способа создания словаря с двумя ключами ‘a’ и ‘b’, каждыйиз которых ассоциирован со значением 0.3. Назовите четыре операции, которые изменяют непосредственно объект списка.4. Назовите четыре операции, которые изменяют непосредственно объект словаря.Ответы1. Литеральное выражение, такое как [0, 0, 0, 0, 0], и операция повторения,такая как [0]*5, создадут список с пятью элементами, содержащими нули.Формально можно было бы построить список с помощью цикла, начинаяс пустого списка, к которому добавляется значение 0 на каждой итерации:L.append(0).
Генератор списков ([0 for i in range(5)]) сделал бы то же самое, нов этом случае пришлось бы выполнить лишнюю работу.Закрепление пройденного2832. Литеральное выражение, например {‘a’: 0, ‘b’: 0}, или последовательностьопераций присваивания, таких как D = {}; D[‘a’] = 0, D[‘b’] = 0, создадут требуемый словарь.
Можно также использовать более новый и более простойспособ с использованием именованных аргументов dict(a=0, b=0) или более гибкий вариант с указанием последовательностей пар ключ/значениеdict([(‘a’, 0), (‘b’, 0)]). Или, поскольку все ключи известны заранее и не будут изменяться в дальнейшем, можно использовать специализированнуюформу dict.fromkeys([‘a’, ‘b’], 0). В версии 3.0 можно также воспользоватьсягенератором словарей: {k:0 for k in ‘ab’}.3. Методы append и extend увеличивают размер самого списка, методы sortи reverse упорядочивают и изменяют порядок следования элементов спискана обратный, метод insert вставляет элемент в указанную позицию, методы remove и pop удаляют элементы списка по значениям и по смещению, инструкция del удаляет элемент списка или срез, а операции присваивания поиндексу или срезу замещают элемент или целый сегмент списка.
Для правильного ответа на вопрос выберите четыре любых метода из указанных.4. Словари прежде всего изменяются с помощью инструкции присваиванияпо новому или по существующему ключу, что приводит к созданию илиизменению записи в таблице. Кроме того, инструкция del удаляет ключ,метод update вклеивает один словарь в другой, а вызов D.pop(key) удаляетключ и возвращает его значение. Словари имеют и другие, более необычныеметоды изменения, которые не были перечислены в этой главе, такие какsetdefault. За дополнительной информацией обращайтесь к справочным руководствам.Глава9.Кортежи, файлы и все остальноеЭта глава завершает наше детальное исследование базовых типов объектов языка Python рассмотрением кортежей – коллекций объектов, которые не могутизменяться, и файлов – интерфейсов к внешним файлам в вашем компьютере.Как вы узнаете, кортежи – это относительно простые объекты, поддерживающие операции, которые по большей части вам уже знакомы по строкам и спискам.