Главная страница

Математический анализ. 3е издание


Скачать 4.86 Mb.
Название3е издание
АнкорМатематический анализ
Дата04.02.2022
Размер4.86 Mb.
Формат файлаpdf
Имя файлаpython_01.pdf
ТипДокументы
#351981
страница94 из 98
1   ...   90   91   92   93   94   95   96   97   98
Часть I. Введение
Упражнения находятся в главе 3, в разделе «Упражнения к первой части».
1. Взаимодействие. Предположим, что настройка Python выполнена правильно, тогда сеанс взаимодействия с интерактивной оболочкой должен выглядеть примерно так, как показано ниже (вы можете за
пустить интерактивную оболочку любым способом, по своему ус
мотрению – в IDLE, из системной командной строки и т. д.):
% python
...строки с информацией об авторских правах...
>>> "Hello World!"
'Hello World!'
>>> # Для выхода используйте CtrlD или CtrlZ, или закройте окно
2. Программы. Содержимое файла (то есть модуля) module1.py и сеанс взаимодействия с командной оболочкой операционной системы должны выглядеть, как показано ниже:
print 'Hello module world!'
% python module1.py
Hello module world!
Вы можете запустить этот файл любым другим способом – щелчком мыши на ярлыке файла, с помощью пункта меню
Run
→Run Module
(
Запустить
→Запустить модуль) и т. д.
3. Модули. Следующий пример сеанса взаимодействия иллюстрирует запуск модуля при его импортировании:
% python
>>> import module1

Решения упражнений
787
Hello module world!
>>>
Не забывайте: чтобы запустить модуль еще раз в течение этого же сеанса работы в интерактивной оболочке, необходимо перезагру
зить его. Просьба переместить файл в другой каталог и снова им
портировать его содержит одну хитрость: если интерпретатор Py
thon создал в первоначальном каталоге файл module1.pyc, при им
порте он будет использовать этот файл, даже если файл с исходным программным кодом (.py) будет перемещен в другой каталог, распо
ложенный за пределами пути поиска модулей. Если интерпретатор имел доступ к файлу с исходным программным кодом, он автомати
чески создаст файл .pyc, содержащий байткод скомпилированной версии модуля. Подробнее о модулях рассказывается в пятой части книги.
4. Сценарии. Предположим, что ваша платформа поддерживает ин
терпретацию комбинации символов #!, решение этого упражнения должно выглядеть примерно так, как показано ниже ( на вашем компьютере в строке #! может потребоваться указать другой путь):
#!/usr/local/bin/python (или #!/usr/bin/env python)
print 'Hello module world!'
% chmod +x module1.py
% module1.py
Hello module world!
5. Ошибки. Ниже показано, какие сообщения об ошибках будут полу
чены по завершении этого упражнения. В действительности вы вы
зываете исключения – по умолчанию при возникновении исключе
ний интерпретатор завершает работу программы и выводит сообще
ние об ошибке вместе содержимым стека вызовов на экран. Инфор
мация из стека показывает, в каком месте программы произошло исключение. В седьмой части книги вы узнаете, как перехватывать исключения с помощью инструкции try и как обрабатывать их. Вы также увидите, что в состав Python входит полноценный отладчик исходного программного кода, обладающий возможностями анали
за ошибок после возникновения исключения. А пока обратите вни
мание, что в случае появления ошибок Python выводит вполне ин
формативные сообщения (вместо того чтобы просто аварийно завер
шать программу вообще без какихлибо сообщений):
% python
>>> 1 / 0
Traceback (innermost last):
File "", line 1, in ?
ZeroDivisionError: integer division or modulo
(ZeroDivisionError: целочисленное деление или деление по модулю)
>>>

788
Приложение B
>>> x
Traceback (innermost last):
File "", line 1, in ?
NameError: x
6. Прерывание программы. Если ввести следующие инструкции:
L = [1, 2]
L.append(L)
тем самым вы создадите циклическую структуру данных. В верси
ях ниже, чем Python 1.5.1, интерпретатор еще не обладает возмож
ностью определять случаи зацикливания в объектах, и он будет вы
водить бесконечный поток [1, 2, [1, 2, [1, 2, [1, 2, и т. д., пока вы не нажмете комбинацию клавиш, выполняющих прерывание программы (которая, с технической точки зрения, возбуждает ис
ключение прерывания с клавиатуры и приводит к выводу сообще
ния по умолчанию). Начиная с версии Python 1.5.1, интерпретатор уже умеет определять случаи зацикливания и вместо бесконечной последовательности выведет [[...]].
Причина зацикливания пока для вас неочевидна; чтобы ее понять,
необходимы знания, которые вы получите во второй части книги.
Однако в двух словах замечу, что операции присваивания в языке
Python всегда создают ссылки на объекты (которые можно предста
вить себе, как неявное следование по указателям). После выполне
ния первой инструкции из тех, что представлены выше, имя L пре
вратится в именованную ссылку на объект списка, состоящий из двух элементов. Списки в языке Python в действительности явля
ются массивами ссылок на объекты, обладающими методом append,
который изменяет сам массив, добавляя ссылку на другой объект.
В данном случае вызов метода append добавляет в конец списка L
ссылку на сам список L, что приводит к зацикливанию, как показа
но на рис. B.1. В некоторых программах, где выполняется обход произвольных объектов, вам, возможно, самим придется опреде
Имена
Объекты
L
1
2
Рис. B.1. Циклический объект, созданный за счет добавления списка
к самому себе. По умолчанию интерпретатор добавляет ссылку
на оригинальный список, а не его копию

Решения упражнений
789
лять такие зацикливания и внимательно изучать действия про
граммы, чтобы избежать зацикливания.
Хотите верьте, хотите нет, но циклические структуры данных ино
гда могут быть полезны (но не тогда, когда выводятся на экран!).
Часть II. Типы и операции
Упражнения находятся в главе 9, в разделе «Упражнения ко второй части».
1. Основы. Ниже приводятся результаты, которые вы должны полу
чить, с некоторыми комментариями к ним. Обратите внимание, что здесь иногда используется символ ;, чтобы поместить несколько инструкций в одну строку. Символ ; – это разделитель инструкций:
# Числа
>>> 2 ** 16 # 2 в степени 16
65536
>>> 2 / 5, 2 / 5.0 # / усекает целые числа, а с плавающей точкой  нет
(0, 0.40000000000000002)
# Строки
>>> "spam" + "eggs" # Конкатенация
'spameggs'
>>> S = "ham"
>>> "eggs " + S
'eggs ham'
>>> S * 5 # Повторение
'hamhamhamhamham'
>>> S[:0] # Пустой срез с первого элемента  [0:0]
''
>>> "green %s and %s" % ("eggs", S) # Форматирование
'green eggs and ham'
# Кортежи
>>> ('x',)[0] # Индексирование кортежа, состоящего из одного
элемента
'x'
>>> ('x', 'y')[1] # Индексирование кортежа, состоящего из двух
элементов
'y'
# Списки
>>> L = [1,2,3] + [4,5,6] # Операции над списками
>>> L, L[:], L[:0], L[ 2], L[ 2:]
([1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6], [], 5, [5, 6])
>>> ([1,2,3]+[4,5,6])[2:4]
[3, 4]
>>> [L[2], L[3]] # Извлечение по смещениям с сохранением в списке
[3, 4]

790
Приложение B
>>> L.reverse(); L # Метод: обратное упорядочивание элементов в списке
[6, 5, 4, 3, 2, 1]
>>> L.sort(); L # Метод: сортировка элементов в списке
[1, 2, 3, 4, 5, 6]
>>> L.index(4) # Метод: смещение первого вхождения 4 (поиск)
3
# Словари
>>> {'a':1, 'b':2}['b'] # Извлечение элемента словаря по ключу
2
>>> D = {'x':1, 'y':2, 'z':3}
>>> D['w'] = 0 # Создаст новую запись
>>> D['x'] + D['w']
1
>>> D[(1,2,3)] = 4 # Использование кортежа в качестве
# ключа (неизменяемый)
>>> D
{'w': 0, 'z': 3, 'y': 2, (1, 2, 3): 4, 'x': 1}
>>> D.keys(), D.values(), D.has_key((1,2,3)) # Методы
(['w', 'z', 'y', (1, 2, 3), 'x'], [0, 3, 2, 4, 1], 1)
# Пустые объекты
>>> [[]], ["",[],(),{},None] # Множество пустых объектов
([[]], ['', [], (), {}, None])
2. Индексирование и извлечение среза. Если попытаться получить доступ к элементу, индекс которого выходит за пределы списка (на
пример, L[4]), будет возбуждено исключение – интерпретатор все
гда проверяет выход за пределы последовательностей.
С другой стороны, операция извлечения среза с использованием индексов, выходящих за пределы последовательности (например,
L[1000:100]
), будет выполнена без ошибок, потому что интерпрета
тор Python всегда корректирует срезы, выходящие за пределы, так,
чтобы они соответствовали границам последовательности (пределы устанавливаются равными нулю и длине последовательности, если это необходимо).
Извлечение последовательности в обратном порядке, когда нижняя граница больше верхней (например, L[3:1]), в действительности ра
ботать не будет. Вы получите пустой срез ([ ]), потому что интерпре
татор скорректирует границы среза так, чтобы нижняя граница оказалась меньше или равна верхней границе (например, выраже
ние L[3:1] будет преобразовано в выражение L[3:3]– пустая позиция со смещением 3). Срезы в языке Python всегда извлекаются слева направо, даже при использовании отрицательных индексов (они сначала будут преобразованы в положительные индексы за счет до
бавления длины последовательности). Обратите внимание, что в Py
thon 2.5 появились срезы с тремя пределами: выражение L[3:1:1]
на самом деле извлекает срез справа налево:

Решения упражнений
791
>>> L = [1, 2, 3, 4]
>>> L[4]
Traceback (innermost last):
File "", line 1, in ?
IndexError: list index out of range
(IndexError: выход индекса за пределы списка)
>>> L[ 1000:100]
[1, 2, 3, 4]
>>> L[3:1]
[]
>>> L
[1, 2, 3, 4]
>>> L[3:1] = ['?']
>>> L
[1, 2, 3, '?', 4]
3. Индексирование, извлечение среза и инструкция del. Сеанс взаимо
действия с интерпретатором должен выглядеть примерно так, как показано ниже. Обратите внимание, что присваивание пустого спи
ска по указанному смещению приведет к сохранению объекта пус
того списка в этой позиции, но присваивание пустого списка срезу приведет к удалению этого среза. Операция присваивания срезу ожидает получить другую последовательность, в противном случае будет получено сообщение о неверном типе операнда – она вставля
ет элементы, находящиеся внутри этой последовательности, а не саму последовательность:
>>> L = [1,2,3,4]
>>> L[2] = []
>>> L
[1, 2, [], 4]
>>> L[2:3] = []
>>> L
[1, 2, 4]
>>> del L[0]
>>> L
[2, 4]
>>> del L[1:]
>>> L
[2]
>>> L[1:2] = 1
Traceback (innermost last):
File "", line 1, in ?
TypeError: illegal argument type for builtin operation
(TypeError: неверный тип аргумента встроенной операции)
4. Кортежи. Значения X и Y поменяются местами. Когда слева и спра
ва от оператора присваивания (=) появляются кортежи, интерпрета
тор выполнит присваивание объектов справа объектам слева в соот
ветствии с их позициями. Это объяснение, пожалуй, самое простое для понимания, хотя целевые объекты слева и не являются настоя

792
Приложение B
щим кортежем несмотря на то, что они именно так и выглядят, – это просто набор независимых имен, которым выполняется присваива
ние. Элементы справа – это кортеж, который распаковывается в про
цессе выполнения операции присваивания (кортеж играет роль временного хранилища присваиваемых данных, необходимого для достижения эффекта обмена):
>>> X = 'spam'
>>> Y = 'eggs'
>>> X, Y = Y, X
>>> X
'eggs'
>>> Y
'spam'
5. Ключи словарей. В качестве ключа словаря может использоваться любой неизменяемый объект, включая целые числа, кортежи, стро
ки и т. д. Это действительно словарь, несмотря на то, что некоторые из его ключей выглядят как целочисленные смещения. Допускает
ся с одним и тем же словарем использовать ключи разных типов:
>>> D = {}
>>> D[1] = 'a'
>>> D[2] = 'b'
>>> D[(1, 2, 3)] = 'c'
>>> D
{1: 'a', 2: 'b', (1, 2, 3): 'c'}
6. Индексирование словарей. Извлечение элемента по несуществую
щему ключу (D['d']) приводит к появлению ошибки. Присваивание по несуществующему ключу (D['d']='spam') создает новый элемент словаря. С другой стороны, выход индекса за границы списка тоже вызывает появление ошибки; ошибкой считается и присваивание по индексу, выходящему за границы списка. Имена переменных на
поминают ключи словаря – прежде чем обратиться к переменным,
им необходимо присвоить значение. Имена переменных, если пона
добится, можно обрабатывать как ключи словарей (они становятся видимы в пространстве имен модуля или в пределах словарей):
>>> D = {'a':1, 'b':2, 'c':3}
>>> D['a']
1
>>> D['d']
Traceback (innermost last):
File "", line 1, in ?
KeyError: d
>>> D['d'] = 4
>>> D
{'b': 2, 'd': 4, 'a': 1, 'c': 3}
>>>
>>> L = [0, 1]

Решения упражнений
793
>>> L[2]
Traceback (innermost last):
File "", line 1, in ?
IndexError: list index out of range
(IndexError: выход индекса за границы списка)
>>> L[2] = 3
Traceback (innermost last):
File "", line 1, in ?
IndexError: list assignment index out of range
(IndexError: присваивание по индексу за границами списка)
7. Общие операции. Ответы на вопросы:

Оператор + не работает с объектами разных типов (например,
строка + список, список + кортеж).

Оператор + не работает со словарями, так как они не являются последовательностями.

Метод append может применяться только к спискам, но не к стро
кам, а метод keys может применяться только к словарям. Метод append предполагает, что целевой объект является изменяемым,
поскольку изменяется сам объект; строки относятся к неизме
няемым типам.

Операции извлечения среза и конкатенации всегда возвращают новый объект того же типа, что и объектыоперанды.
>>> "x" + 1
Traceback (innermost last):
File "", line 1, in ?
TypeError: illegal argument type for builtin operation
(TypeError: неверный тип аргумента встроенной операции)
>>>
>>> {} + {}
Traceback (innermost last):
File "", line 1, in ?
TypeError: bad operand type(s) for +
(TypeError: неверный тип операнда(ов) для +)
>>>
>>> [].append(9)
>>> "".append('s')
Traceback (innermost last):
File "", line 1, in ?
AttributeError: attributeless object
(AttributeError: объект без атрибутов)
>>>
>>> {}.keys()
[]
>>> [].keys()
Traceback (innermost last):
File "", line 1, in ?
AttributeError: keys
(AttributeError: ключи)

794
Приложение B
>>>
>>> [][:]
[]
>>> ""[:]
''
8. Индексирование строк. Так как строки представляют собой кол
лекции односимвольных строк, каждый раз, когда извлекается элемент строки, возвращается строка, из которой также допускает
ся извлекать элементы по индексам. Выражение S[0][0][0][0][0]
всего лишь извлекает первый символ снова и снова. Этот прием не
применим к спискам (списки могут хранить объекты произволь
ных типов), если список не содержит строки:
>>> S = "spam"
>>> S[0][0][0][0][0]
's'
>>> L = ['s', 'p']
>>> L[0][0][0]
's'
9. Неизменяемые типы. Правильными являются оба следующих ре
шения. Присваивание по индексу недопустимо, потому что строки являются неизменяемыми объектами:
>>> S = "spam"
>>> S = S[0] + 'l' + S[2:]
>>> S
'slam'
>>> S = S[0] + 'l' + S[2] + S[3]
>>> S
'slam'
10. Вложенные структуры. Ниже приводится пример такой структуры:
>>> me = {'name':('mark', 'e', 'lutz'), 'age':'?', 'job':'engineer'}
>>> me['job']
'engineer'
>>> me['name'][2]
'lutz'
11. Файлы. Ниже приводится пример одного из способов создания фай
ла и чтения информации из него в языке Python (ls – это команда
UNIX, в Windows вместо нее следует использовать команду dir):
# Файл: maker.py file = open('myfile.txt', 'w')
file.write('Hello file world!\n') # Или: open().write()
file.close() # закрывать файл не всегда обязательно
# Файл: reader.py file = open('myfile.txt') # 'r'  режим открытия по умолчанию
print file.read() # Или print open().read()

Решения упражнений
795
% python maker.py
% python reader.py
Hello file world!
% ls l myfile.txt
rwxrwxrwa 1 0 0 19 Apr 13 16:33 myfile.txt
12. Функция dir. Ниже показано, что будет получено в случае списков.
Для словарей будет получена та же информация, но имена методов будут другими. Обратите внимание, действие функции dir в Py
thon 2.2 было расширено – она дополнительно выводит имена, на
чинающиеся и заканчивающиеся символами подчеркивания, кото
рые реализуют операторы выражений и могут быть унаследованы подклассами, как описывается в шестой части книги. Атрибут
__methods__
был удален в версии Python 2.2 изза его противоречи
вой реализации – используйте вместо него функцию dir для извле
чения списка атрибутов:
>>> [].__methods__
['append', 'count', 'index', 'insert', 'remove', 'reverse', 'sort',...]
>>> dir([])
['append', 'count', 'index', 'insert', 'remove', 'reverse', 'sort',...]
Часть III. Инструкции и синтаксис
Упражнения находятся в главе 14, в разделе «Упражнения к третьей части».
1. Основы циклов. При выполнении этого упражнения вы получите примерно такой программный код:
>>> S = 'spam'
>>> for c in S:
... print ord(c)
115 112 97 109
>>> x = 0
>>> for c in S: x += ord(c) # Или: x = x + ord(c)
>>> x
433
>>> x = []
>>> for c in S: x.append(ord(c))
>>> x
[115, 112, 97, 109]
>>> map(ord, S)
[115, 112, 97, 109]

796
Приложение B
2. Символы обратного слеша. Пример выводит символ подачи звуко
вого сигнала (\a) 50 раз – здесь предполагается, что ваш компьютер в состоянии воспроизвести его, поэтому при запуске этого фрагмен
та не под управлением IDLE вы можете получить серию звуковых сигналов (или один длинный сигнал, если ваш компьютер обладает достаточно высоким быстродействием). Эй! Я предупреждал вас!
3. Сортировка словарей. Ниже приводится один из возможных вари
антов решения этого упражнения (вернитесь к главе 8, если чтото показалось вам непонятным). Не забывайте, что вам необходимо разделить вызовы методов keys и sort, как это сделано здесь, потому что метод sort возвращает объект None. Начиная с версии Python 2.2
появилась возможность организовать итерации по ключам словаря без вызова метода keys (например, for key in D:), но ключи не будут отсортированы этим программным кодом. В самых свежих версиях
Python того же эффекта можно добиться с помощью встроенной функции sorted:
>>> D = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7}
>>> D
{'f': 6, 'c': 3, 'a': 1, 'g': 7, 'e': 5, 'd': 4, 'b': 2}
>>>
>>> keys = D.keys()
>>> keys.sort()
>>> for key in keys:
... print key, '=>', D[key]
a => 1
b => 2
c => 3
d => 4
e => 5
f => 6
g => 7
>>> for key in sorted(D): # В наиболее свежих версиях Pythons
... print key, '=>', D[key]
4. Программирование альтернативной логики. Ниже приводятся не
сколько вариантов решения этого упражнения. Ваши решения мо
гут несколько отличаться – цель этого упражнения состоит в том,
чтобы дать вам возможность поэкспериментировать с созданием альтернативных ветвей исполнения программы, поэтому приветст
вуются любые правильные решения:
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
i = 0
while i < len(L):
if 2 ** X == L[i]:
print 'at index', i

Решения упражнений
797
break i = i+1
else:
print X, 'not found'
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
for p in L:
if (2 ** X) == p:
print (2 ** X), 'was found at', L.index(p)
break else:
print X, 'not found'
L = [1, 2, 4, 8, 16, 32, 64]
X = 5
if (2 ** X) in L:
print (2 ** X), 'was found at', L.index(2 ** X)
else:
print X, 'not found'
X = 5
L = []
for i in range(7): L.append(2 ** i)
print L
if (2 ** X) in L:
print (2 ** X), 'was found at', L.index(2 ** X)
else:
print X, 'not found'
X = 5
L = map(lambda x: 2**x, range(7))
print L
if (2 ** X) in L:
print (2 ** X), 'was found at', L.index(2 ** X)
else:
print X, 'not found'
1   ...   90   91   92   93   94   95   96   97   98


написать администратору сайта