Учебник Python 3.1. Учебник Python 3. Учебник Python 1 Материал из Викиучебника. Оглавление
Скачать 1.85 Mb.
|
Учебник Python 3.1: Материал из Викиучебника. присваивание на самом деле является лишь комбинацией упаковки кортежа и распаковки последовательности. Здесь есть некоторая асимметрия: упаковка нескольких значений всегда создаёт кортеж, а распаковка работает для любой последовательности. Множества Python имеет также тип данных множество. Множество — это неупорядоченная коллекция без дублирующихся элементов. Основные способы использования — проверка на вхождение и устранение дублирующихся элементов. Объекты этого типа поддерживают обычные математические операции над множествами, такие как объединение, пересечение, разность и симметрическая разность. Для создания множеств могут быть использованы фигурные скобки или функция set(). Заметьте: Для создания пустого множества нужно использовать set() , а не {} : в последнем случае создаётся пустой словарь (dictionary) — тип данных, который мы обсудим в следующем разделе. Продемонстрируем работу с множествами на небольшом примере [35] : >>> basket = { 'apple' , 'orange' , 'apple' , 'pear' , 'orange' , 'banana' } >>> (basket) { 'orange' , 'banana' , 'pear' , 'apple' } >>> fruit_list = [ 'apple' , 'orange' , 'apple' , 'pear' , 'orange' , 'banana' ] >>> fruit = set (fruit_list) # создать множество на основе данных из списка (заметьте исчезновение дубликатов -перев.) >>> fruit { 'orange' , 'pear' , 'apple' , 'banana' } >>> fruit = { 'orange' , 'apple' } # синтаксис {} эквивалентен [] у списков >>> fruit { 'orange' , 'apple' } >>> 'orange' in fruit # быстрая проверка на вхождение True >>> 'crabgrass' in fruit False >>> # Демонстрация операций со множествами на примере букв из двух слов >>> a = set ( 'abracadabra' ) >>> b = set ( 'alacazam' ) >>> a # уникальные буквы в a { 'a' , 'r' , 'b' , 'c' , 'd' } >>> a - b # буквы в a но не в b { 'r' , 'd' , 'b' } >>> a | b # все буквы, которые встречаются в a или в b { 'a' , 'c' , 'r' , 'd' , 'b' , 'm' , 'z' , 'l' } >>> a & b # буквы, которые есть и в a и в b { 'a' , 'c' } >>> a ^ b # буквы в a или в b, но не в обоих { 'r' , 'd' , 'b' , 'm' , 'z' , 'l' } Как и у списков, у множеств существует синтаксис сборок: >>> a = {x for x in 'abracadabra' if x not in 'abc' } >>> a { 'r' , 'd' } 37 Учебник Python 3.1: Материал из Викиучебника. Словари Другой полезный встроенный в Python тип данных — это словарь (dictionary) (см. — Справочник по библиотеке Связывающие типы ). Словари иногда встречаются в других языках в виде «ассоциативных записей» или «ассоциативных массивов». В отличие от последовательностей, которые индексируются по диапазону чисел, словари индексируются по ключам(keys), которые, в свою очередь, могут быть любого неизменяемого типа; строки и числа всегда могут быть ключами. Кортежи могут быть ключами только если они составлены из строк, чисел или кортежей; если кортеж содержит какой-либо изменяемый объект, явно или неявно, то он не может быть использован в качестве ключа. Вы не можете использовать списки в роли ключей, поскольку списки могут быть изменены на месте присваиванием по индексу, присваиванием по срезу или такими методами как append() и extend() Лучше всего воспринимать словарь как неупорядоченный набор пар ключ: значение с требованием, чтобы ключи были уникальны (в пределах одного словаря). Пара скобок создает пустой словарь: {} . Указывая разделённый запятыми список пар ключ: значение внутри скобок, вы задаёте содержимое словаря; в таком же формате словарь можно вывести. Главные операции над словарём — это сохранение значения с каким-либо ключом и извлечение значения по указанному ключу. Также возможно удалить пару ключ: значениеиспользуя оператор del . Если вы сохраняете значение используя ключ, который уже встречается в словаре — старое значение, ассоциированное с этим ключом, стирается. Извлечение значения по несуществующему ключу вызывает ошибку. Выполнение конструкции list(d.keys()) с объектом словаря возвращает список всех ключей, использующихся в словаре, в случайном порядке (если вы хотите отсортировать его, к списку ключей можно применить функцию sorted() ). Чтобы проверить, содержит ли словарь определённый ключ, используйте ключевое слово in Вот небольшой пример использования словарей: >>> tel = { 'jack' : 4098 , 'sape' : 4139 } >>> tel[ 'guido' ] = 4127 >>> tel { 'sape' : 4139 , 'guido' : 4127 , 'jack' : 4098 } >>> tel[ 'jack' ] 4098 >>> del tel[ 'sape' ] >>> tel[ 'irv' ] = 4127 >>> tel { 'guido' : 4127 , 'irv' : 4127 , 'jack' : 4098 } >>> list (tel.keys()) [ 'irv' , 'guido' , 'jack' ] >>> sorted (tel.keys()) [ 'guido' , 'irv' , 'jack' ] >>> 'guido' in tel True >>> 'jack' not in tel False Конструктор dict() строит словарь непосредственно на основе пар ключей и значений, где каждая пара представлена в виде кортежа. Когда пары могут быть сформированы шаблоном, списковые сборки помогут описать список пар более компактно. 38 Учебник Python 3.1: Материал из Викиучебника. >>> dict ([( 'sape' , 4139 ) , ( 'guido' , 4127 ) , ( 'jack' , 4098 )]) { 'sape' : 4139 , 'jack' : 4098 , 'guido' : 4127 } В дополнение ко всему этому, для создания словарей из произвольных выражений для ключей и значений, могут быть использованы словарные сборки: >>> {x: x** 2 for x in ( 2 , 4 , 6 )} { 2 : 4 , 4 : 16 , 6 : 36 } Позже в учебнике мы изучим выражения-генераторы (Generator Expressions), которые даже лучше подходят для снабжения конструктора dict() парами ключ-значение. Если ключи являются простыми строками, иногда легче описать пары используя именованные параметры: >>> dict (sape = 4139 , guido = 4127 , jack = 4098 ) { 'sape' : 4139 , 'jack' : 4098 , 'guido' : 4127 } Организация циклов При организации перебора элементов из словаря ключ и соответствующее ему значение могут быть получены одновременно посредством метода items() >>> knights = { 'gallahad' : 'the pure' , 'robin' : 'the brave' } >>> for k , v in knights.items(): (k , v) gallahad the pure robin the brave Функция enumerate() поможет пронумеровать элементы перебираемой в цикле последовательности: >>> for i , v in enumerate ([ 'tic' , 'tac' , 'toe' ]): (i , v) 0 tic 1 tac 2 toe Для того, чтобы организовать цикл параллельно для двух или более последовательностей, элементы можно предварительно сгруппировать функцией zip() [36] >>> questions = [ 'name' , 'quest' , 'favorite color' ] >>> answers = [ 'lancelot' , 'the holy grail' , 'blue' ] >>> for q , a in zip (questions , answers): ( 'What is your {0}? It is {1}.' .format(q , a)) What is your name? It is lancelot. What is your quest? It is the holy grail. What is your favorite color? It is blue. Изменить порядок следования последовательности на обратный поможет функция reversed() >>> for i in reversed ( range ( 1 , 10 , 2 )): (i) 9 7 5 3 1 39 Учебник Python 3.1: Материал из Викиучебника. Для организации цикла по отсортированной последовательности можно применить функцию sorted() , которая возвращает отсортированный список, оставляя исходный без изменений. >>> basket = [ 'apple' , 'orange' , 'apple' , 'pear' , 'orange' , 'banana' ] >>> for f in sorted ( set (basket)): (f) apple banana orange pear Подробнее об условиях Условия в операторах if и while могут содержать любые операции, а не только операции сравнения. Операции сравнения in и not in проверяют, встречается значение в последовательности или нет. Операции is и is not проверяют, не являются ли два объекта на самом деле одним и тем же (это имеет смысл лишь для изменяемых объектов, таких как списки). Все операции сравнения имеют один и тот же приоритет, меньший чем у любых операций над числами. Сравнения можно объединять в цепочки. Например, a < b == c проверяет, меньше ли a чем b и, сверх того, равны ли b и c Сравнения могут быть скомбинированы с использованием булевых операций and и or , а результат сравнения (или любого другого булева выражения) можно отрицать используя not . Эти операции имеют меньший приоритет, чем у операций сравнения; среди них у not высший приоритет, а у or — низший, поэтому A and not B or C эквивалентно (A and (not B)) or C . Как всегда, явно заданные скобки помогут выразить желаемый порядок выполнения операций. Булевы операции and и or — это так называемые коротящие операции [37] (short-circuit operators): их операнды вычисляются слева направо и вычисление заканчивается как только результат становится определён (очевиден). Например, если A и C истинны, а B — ложно, в условии A and B and C выражение C не вычисляется. Коротящая операциявозвращает последний элемент, который был вычислен, что может быть применено не только в целях задания логики. Можно присвоить результат сравнения, или другого булева выражения, переменной. Например, >>> string1 , string2 , string3 = '' , 'Trondheim' , 'Hammer Dance' >>> non_null = string1 or string2 or string3 >>> non_null 'Trondheim' Заметьте, что в Python (в отличие от C) присваивание не может использоваться внутри выражений. Программисты на C могут возмутиться по этому поводу, но на самом деле это позволяет избежать ряда проблем, обычного для программ на C: указания оператора присваивания ( = ) в выражении, вместо предполагавшегося сравнения ( == ). 40 Учебник Python 3.1: Материал из Викиучебника. Сравнение последовательностей и других типов Объекты последовательностей можно сравнивать с другими объектами с тем же типом последовательности. Сравнение использует лексикографический порядок: сравниваются первые два элемента, и если они различны — результат сравнения определён; если они равны, сравниваются следующие два элемента и так далее до тех пор, пока одна из последовательностей не будет исчерпана. Если сравниваемые два элемента сами являются последовательностями одного типа, лексикографическое сравнение происходит в них рекурсивно. Если все элементы обоих последовательностей оказались равны, последовательности считаются равными. Если одна последовательность оказывается стартовой последовательностью другой, более короткая последовательность считается меньшей. Лексикографическое упорядочивание строк использует порядок в таблице Unicode для индивидуальных символов. Несколько примеров сравнений между однотипными последовательностями: ( 1 , 2 , 3 ) < ( 1 , 2 , 4 ) [ 1 , 2 , 3 ] < [ 1 , 2 , 4 ] "Пайтон" < "Паскаль" < "Си" < "Си++" ( 1 , 2 , 3 , 4 ) < ( 1 , 2 , 4 ) ( 1 , 2 ) < ( 1 , 2 , - 1 ) ( 1 , 2 , 3 ) == ( 1.0 , 2.0 , 3.0 ) ( 1 , 2 , ( 'aa' , 'ab' ) , 4 ) < ( 1 , 2 , ( 'abc' , 'a' )) Обратите внимание, что сравнение объектов различных типов операциями < или > позволено, если объекты имеют соответствующие методы сравнения. Например, смешанные числовые типы сравниваются в соответствии с их численными значениями, так что 0 равен 0.0 и т.д. В противном случае интерпретатор, прервав процесс сортировки, возбудит исключение TypeError Модули Если вы выйдете из интерпретатора и зайдёте в него снова, то все определённые вами имена (функции и переменные) будут потеряны. По этой причине, если вы захотите написать несколько более длинную программу, вам лучше использовать текстовый редактор для подготовки ввода для интерпретатора и запускать последний в режиме файлового ввода. Это называется созданием сценария. Если ваша программа становится обширнее, вы можете предпочесть разделить её на несколько файлов для удобства эксплуатации. Также вы можете захотеть использовать сразу в нескольких программах некоторую полезную функцию, написанную вами, не копируя её определение каждый раз. В языке Python можно поместить требуемые определения в файл и использовать их в сценариях или в интерактивном режиме интерпретатора. Такой файл называется модулем(module). Определения из модуля могут быть импортированы в других модулях, либо в главном модуле (собрание переменных, к которым есть доступ в сценарии, который непосредственно запускается, и в интерактивном режиме). Модуль — это файл, содержащий определения и операторы Python. Именем файла является имя модуля с добавленным суффиксом .py. Внутри модуля, имя модуля (в качестве строки) доступно в виде значения глобальной переменной с именем __name__ Например, используя ваш любимый текстовый редактор, создайте в текущем каталоге файл с именемfibo.py со следующим содержимым: """Модуль вычисления чисел Фибоначчи""" 41 Учебник Python 3.1: Материал из Викиучебника. def fib(n): # вывести числа Фибоначчи вплоть до n a , b = 0 , 1 while b < n: (b , end = ' ' ) a , b = b , a+b () def fib2(n): # вернуть числа Фибоначчи вплоть до n result = [] a , b = 0 , 1 while b < n: result.append(b) a , b = b , a+b return result Теперь можно войти в интерпретатор Python и импортировать этот модуль следующей командой: >>> import fibo Это действие не переводит имена определённых в модуле функций в текущую таблицу символов, а лишь имя модуля fibo . Используя имя модуля, вы можете получить доступ к функциям: >>> fibo.fib( 1000 ) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 >>> fibo.fib2( 100 ) [ 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , 55 , 89 ] >>> fibo.__name__ 'fibo' Если вы собираетесь использовать функцию часто, можно присвоить её локальному имени: >>> fib = fibo.fib >>> fib( 500 ) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 Подробнее о модулях Помимо определений функций модуль может содержать исполняемые операторы. Назначение этих операторов — инициализация модуля: они выполняются при первом импортировании модуля где-либо [38] Каждый модуль имеет свою собственную таблицу символов, которая используется в качестве глобальной всеми определёнными в модуле функциями. Таким образом, автор модуля может использовать глобальные символы в модуле, не опасаясь неожиданных совпадений с глобальными переменными пользователя. С другой стороны, если вы знаете, что делаете, можно сослаться на глобальные переменные модуля, пользуясь той же нотацией, которая применялась для ссылок на его функции: <имя_модуля>.<имя_элемента>. Модули могут импортировать другие модули. Не требуется указывать все операторы import в начале модуля (или сценария, с той же целью), но обычно так и делается. Имена из импортированного модуля добавляются в глобальную таблицу символов модуля его импортирующего. Есть вариант оператора import , который переносит имена из модуля прямо в таблицу символов импортирующего модуля. Например: >>> from fibo import fib , fib2 >>> fib( 500 ) 42 Учебник Python 3.1: Материал из Викиучебника. 1 1 2 3 5 8 13 21 34 55 89 144 233 377 При этом имя самого модуля, из которого переносятся имена элементов, не добавляется в локальную таблицу символов (так, в этом примере, имя fibo не определено) И есть даже способ импортировать все имена, которые определяет данный модуль: >>> from fibo import * >>> fib( 500 ) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 Импортируются все имена, кроме тех, которые начинаются на подчёркивание ( _ ). В большинстве случаев программисты на Python не используют эту возможность, поскольку она внедряет в интерпретатор целый набор новых неизвестных имён и может скрыть некоторые объекты, которые вы уже определили. ☞ Для повышения эффективности, каждый модуль импортируется лишь единожды за сеанс работы с интерпретатором. Поэтому, если вы изменили ваши модули, вам придётся перезапустить интерпретатор. Или, если вам нужно перезагрузить конкретный модуль, можно использовать imp.reload() таким образом: import imp; imp.reload(<имя_модуля>) |