Python Tutorial 2
4.1 Оператор if
Пример :
>>> x = int(raw_input("Please enter an integer: "))
>>> if x < 0:
... x = 0
... print 'Negative changed to zero'
... elif x == 0:
... print 'Zero'
... elif x == 1:
... print 'Single'
... else:
... print 'More'
...
4.2 Оператор for
Этот оператор имеет некоторую специфику .
Помимо традиционной итерации , итерация в питоне может быть автоматическая ,
как для элементов списка , так и строки .
>>> # Measure some strings:
... a = ['cat', 'window', 'defenestrate']
>>> for x in a:
... print x, len(x)
...
cat 3
window 6
defenestrate 12
При этом модификацию списка внутри цикла проводить нежелательно .
Если уж совсем никак , то лучше манипулировать над копией .
>>> for x in a[:]: # make a slice copy of the entire list
... if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']
4.3 Функция range()
Если вам нужна последовательность чисел для итерации ,
на помощь приходит функция range():
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Можно установить диапазон последовательности или инкремент :
>>> range(5, 10)
[5, 6, 7, 8, 9]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(-10, -100, -30)
[-10, -40, -70]
Использование в цикле пары
range() и len() :
>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print i, a[i]
...
0 Mary
1 had
2 a
3 little
4 lamb
4.4 break , continue ,
else в циклах .
break досрочно прекращает циклы
for и while .
continue переходит на следующую итерацию цикла.
Пример использования else :
>>> for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... # loop fell through without finding a factor
... print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
4.5 Оператор pass
pass ничего не делает , его используют тогда , когда ветку
нужно хоть чем-нибудь заполнить :
>>> while True:
... pass # Busy-wait for keyboard interrupt
...
4.6 Определение функций
Пример функции Фибоначчи :
>>> def fib(n): # write Fibonacci series up to n
... """Print a Fibonacci series up to n."""
... a, b = 0, 1
... while b < n:
... print b,
... a, b = b, a+b
...
>>> # Now call the function we just defined:
... fib(2000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
Ключевое слово def является определением функции .
После него идет имя функции и список параметров .
Тело функции начинается со следующей строки и с отступа , как правило это комментарий .
Дальше идут локальные переменные . Внутри функции можно ссылаться на глобальные переменные
В питоне можно имя функции присваивать другой переменной и потом ссылаться на эту переменную ,
тем самым вызывая первичную функцию :
>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
1 1 2 3 5 8 13 21 34 55 89
Процедуры в питоне почти ничем не отличаются от функций , за исключением того ,
что они ничего не возвращают , вернее , возвращают значение , которое называется
None :
Функция , которая возвращает , а не печатает числа Фибоначчи :
>>> def fib2(n): # return Fibonacci series up to n
... """Return a list containing the Fibonacci series up to n."""
... result = []
... a, b = 0, 1
... while b < n:
... result.append(b) # see below
... a, b = b, a+b
... return result
...
>>> f100 = fib2(100) # call it
>>> f100 # write the result
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Можно определить функцию с переменным числом аргументов :
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while True:
ok = raw_input(prompt)
if ok in ('y', 'ye', 'yes'): return True
if ok in ('n', 'no', 'nop', 'nope'): return False
retries = retries - 1
if retries < 0: raise IOError, 'refusenik user'
print complaint
Эта функция может быть вызвана так :
ask_ok('Do you really want to quit?') или так:
ask_ok('OK to overwrite the file?', 2) .
Пример :
def f(a, L=[]):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
Будет напечатано
Можно фиксировать число аргументов :
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
4.7.2 Аргументы-ключи
Функция может быть вызвана с использованием ключей-аргуметов :
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print "-- This parrot wouldn't", action,
print "if you put", voltage, "Volts through it."
print "-- Lovely plumage, the", type
print "-- It's", state, "!"
Вызов правильный:
parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')
Неверный вызов:
parrot() # required argument missing
parrot(voltage=5.0, 'dead') # non-keyword argument following keyword
parrot(110, voltage=220) # duplicate value for argument
parrot(actor='John Cleese') # unknown keyword
Следующая интересная фича питона :
Параметр , представленный в определении функции в форме **name есть ссылка на хэш .
Параметр , представленный в определении функции в форме *name есть ссылка на массив %
def cheeseshop(kind, *arguments, **keywords):
print "-- Do you have any", kind, '?'
print "-- I'm sorry, we're all out of", kind
for arg in arguments: print arg
print '-'*40
keys = keywords.keys()
keys.sort()
for kw in keys: print kw, ':', keywords[kw]
И вызов такой :
cheeseshop('Limburger', "It's very runny, sir.",
"It's really very, VERY runny, sir.",
client='John Cleese',
shopkeeper='Michael Palin',
sketch='Cheese Shop Sketch')
Будет распечатано :
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch
Порядок вызова аргументов функции тоже не имеет существенного значения :
def fprintf(file, format, *args):
file.write(format % args)
Если параметром функции является список , можно при вызове просто сослаться на него :
>>> range(3, 6) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args) # call with arguments unpacked from a list
[3, 4, 5]
4.7.5 Lambda
В питон добавлено несколько фич из Лиспа , например создание анонимных функций
с помощью ключевого слова lambda .
Пример суммы 2-х аргументов :
"lambda a, b: a+b".
Lambda может быть использована в любом месте .
Пример инкремента :
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
5. Data Structures
5.1 Lists
Списки - то бишь массивы - имеют несколько методов
-
Добавляет элемент в конец , эквивалент
a[len(a):] = [x] .
-
Добавляет массив в конец данного массива , эквивалент
a[len(a):] = L .
-
Вставляет элемент в данную позицию,
a.insert(0, x)
вставляет в начало,и a.insert(len(a), x)
эквивалентно a.append(x) .
-
Удаляет первый элемент из массива
-
Удаляет данную позицию
-
Возвращает индекс первого найденного значения x.
-
Возвращает число найденных значений x
-
Сортировка
-
Реверс массива
Примеры :
>>> a = [66.25, 333, 333, 1, 1234.5]
>>> print a.count(333), a.count(66.25), a.count('x')
2 1 0
>>> a.insert(2, -1)
>>> a.append(333)
>>> a
[66.25, 333, -1, 333, 1, 1234.5, 333]
>>> a.index(333)
1
>>> a.remove(333)
>>> a
[66.25, -1, 333, 1, 1234.5, 333]
>>> a.reverse()
>>> a
[333, 1234.5, 1, 333, -1, 66.25]
>>> a.sort()
>>> a
[-1, 1, 66.25, 333, 333, 1234.5]
5.1.1 Массивы - стеки
Методы массива наглядно демонстрируют реализацию стека - "поседний вошел - первый вышел" :
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
5.1.2 Массив-очередь
Рассмотрим реализацию очереди , построенной по принципу - "первый вошел - первый вышел"
>>> queue = ["Eric", "John", "Michael"]
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.pop(0)
'Eric'
>>> queue.pop(0)
'John'
>>> queue
['Michael', 'Terry', 'Graham']
5.1.3 Functional Programming Tools
Рассмотрим 3 встроенных функции массивов : filter(), map(), reduce().
"filter(function, sequence)" возвращает такую последовательность ,
для значений которых справедлива function(item) , например :
>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]
"map(function, sequence)" вызывает
function(item) для каждого значения :
>>> def cube(x): return x*x*x
...
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
Может быть передано несколько последовательностей :
>>> seq = range(8)
>>> def add(x, y): return x+y
...
>>> map(add, seq, seq)
[0, 2, 4, 6, 8, 10, 12, 14]
"reduce(func, sequence)" возвращает единственное значение ,
полученное вызовом функции func для первых 2-х членов последовательности ,затем для результата
и следующего значения , и т.д. :
>>> def add(x,y): return x+y
...
>>> reduce(add, range(1, 11))
55
Условные массивы получаются с применением операторов for и if .
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> vec = [2, 4, 6]
>>> [3*x for x in vec]
[6, 12, 18]
>>> [3*x for x in vec if x > 3]
[12, 18]
>>> [3*x for x in vec if x < 2]
[]
>>> [[x,x**2] for x in vec]
[[2, 4], [4, 16], [6, 36]]
>>> [x, x**2 for x in vec] # error - parens required for tuples
File "<stdin>", line 1, in ?
[x, x**2 for x in vec]
^
SyntaxError: invalid syntax
>>> [(x, x**2) for x in vec]
[(2, 4), (4, 16), (6, 36)]
>>> vec1 = [2, 4, 6]
>>> vec2 = [4, 3, -9]
>>> [x*y for x in vec1 for y in vec2]
[8, 6, -18, 16, 12, -36, 24, 18, -54]
>>> [x+y for x in vec1 for y in vec2]
[6, 5, -7, 8, 7, -5, 10, 9, -3]
>>> [vec1[i]*vec2[i] for i in range(len(vec1))]
[8, 12, -54]
Условные массивы могут быть использованы для составных функций :
>>> [str(round(355/113.0, i)) for i in range(1,6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']
5.2 Оператор del
Используется для удаления по индексу , а не по значению :
>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
del может быть использован для удаления переменных :
5.3 Tuples и Sequences
tuple - набор значений , разделенных запятыми :
>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
Нельзя для Tuples индивидуально добавить или назначить значения ,
это неизменяемые последовательности .
5.4 Sets
set - набор уникальных элементов :
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> fruits = set(basket) # create a set without duplicates
>>> fruits
set(['orange', 'pear', 'apple', 'banana'])
>>> 'orange' in fruits # fast membership testing
True
>>> 'crabgrass' in fruits
False
>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> a - b # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # letters in both a and b
set(['a', 'c'])
>>> a ^ b # letters in a or b but not both
set(['r', 'd', 'b', 'm', 'z', 'l'])
5.5 Dictionaries
Словари - или хэши - их еще называют ассоциативными массивами .
Словари индексируются по ключам , а не по порядку . Ключи - неизменяемый тип .
Словарь - неотсортированный набор - set - пар
key: value , с обязательным требованием уникальности для ключей .
Пара пустых фигурных скобок создает пустой словарь : {} .
Удаляется пара с помощью del .
Если вы сохраняете пару с ключем , который уже есть , старое значение затрется .
Метод keys() возвращает массив всех ключей .
Для проверки наличия ключа используется has_key() .
Пример:
>>> 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}
>>> tel.keys()
['guido', 'irv', 'jack']
>>> tel.has_key('guido')
True
Конструктор dict() можно использовать для прямой трансляции масиива в хэш :
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
>>> dict([(x, x**2) for x in vec]) # use a list comprehension
{2: 4, 4: 16, 6: 36}
5.6 Работа с циклами
В цикле пара может быть возвращена из словаря с помощью метода iteritems() method.
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.iteritems():
... print k, v
...
gallahad the pure
robin the brave
Индекс может быть возвращен с помощью метода enumerate() function.
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print i, v
...
0 tic
1 tac
2 toe
Для задания цикла для двух и более последовательностей может быть использована
функция zip() function.
>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print 'What is your %s? It is %s.' % (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(xrange(1,10,2)):
... print i
...
9
7
5
3
1
Для задания сортированного цикла - sorted()
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
... print f
...
apple
banana
orange
pear
5.8 Сравнение последовательностей .
Элементы 2-х последовательностей сравниваются до первого расхождения .
Если все сравниваемые значения одинаковы , то и последовательности одинаковы .
(1, 2, 3) < (1, 2, 4)
[1, 2, 3] < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(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')) < (1, 2, ('abc', 'a'), 4)
Сравнение 2-х обектов разных типов легально . Но при этом : массив всегда меньше ,
чем строка , строка всегда меньше чем tuple :-)
7. Input / Output
Вывод программы может идти на экран или записываться в файл .
Подчастую необходимо произвольным образом форматировать вывод .
Есть 2 пути - первый использует возможности стандартного модуля string , второй - использование оператора % со строкой в качестве аргумента.
Оператор % использует аргумент в стиле sprintf()-style форматирования , знакомого из с-программирования .
В питоне есть возможность для конвертация любого типа в строку - для этого существуют
функции repr() или str() . Обратные кавычки
(`` ) эквивалентны repr().
Числа , списки одинаково интерпретируются этими двумя функциями .
Пример:
>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> repr(s)
"'Hello, world.'"
>>> str(0.1)
'0.1'
>>> repr(0.1)
'0.10000000000000001'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'
>>> print s
The value of x is 32.5, and y is 40000...
>>> # The repr() of a string adds string quotes and backslashes:
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print hellos
'hello, world\n'
>>> # The argument to repr() may be any Python object:
... repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam', 'eggs'))"
>>> # reverse quotes are convenient in interactive sessions:
... `x, y, ('spam', 'eggs')`
"(32.5, 40000, ('spam', 'eggs'))"
Распечатка квадратов и кубов ::
>>> for x in range(1, 11):
... print repr(x).rjust(2), repr(x*x).rjust(3),
... # Note trailing comma on previous line
... print repr(x*x*x).rjust(4)
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
>>> for x in range(1,11):
... print '%2d %3d %4d' % (x, x*x, x*x*x)
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
Строковая функция rjust() добавляет фиксированное число пробелов .
С помощью метода zfill()можно добавить фиксированное количество нулей :
>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'
Использование % :
>>> import math
>>> print 'The value of PI is approximately %5.3f.' % math.pi
The value of PI is approximately 3.142.
Форматирование может быть множественным :
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
... print '%-10s ==> %10d' % (name, phone)
...
Jack ==> 4098
Dcab ==> 7678
Sjoerd ==> 4127
C-форматы %n and %p не поддерживаются .
При форматировании можно делать ссылки на имя переменной с помощью %(name)format :
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print 'Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d' % table
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
Это полезно в комбинации со встроенной функцией vars() , которая возвращает словарь.
7.2 Работа с файлами
open() возвращает файловый обьект
и включает 2 аргумента : "open(filename, mode)".
>>> f=open('/tmp/workfile', 'w')
>>> print f
<open file '/tmp/workfile', mode 'w' at 80a0960>
Первый аргумент - имя файла , второй - способ открытия файла .
mode может быть 'r' когда файл на чтение , 'w' для записи
в существующий файл , и 'a' для добавления в файл .
'r+' открывает файл для чтения и для записи .
Параметр mode может быть опущен ; в этом случае по умолчанию будет 'r'
На Windows и на Macintosh, 'b' открывает файл в бинарном режиме , поэтому здесь возможны варианты
'rb' , 'wb' , and 'r+b' .
The rest of the examples in this section will assume that a file
object called f has already been created.
Для чтения контента файла есть вызов f.read(size) , который возвращает порцию данных
в форме строки . size - опциональный числовой аргумент .
>>> f.read()
'This is the entire file.\n'
>>> f.read()
''
f.readline() читает строку ; символ новой строки (\n ) будет в ее начале и конце. Если f.readline() возвращает пустую строку , достигнут конец файла .
>>> f.readline()
'This is the first line of the file.\n'
>>> f.readline()
'Second line of the file\n'
>>> f.readline()
''
f.readlines() возвращает все строки файла .
Она может быть использована для чтения порции из большого файла :
>>> f.readlines()
['This is the first line of the file.\n', 'Second line of the file\n']
f.write(string) пишет string в файл , возвращая None .
>>> f.write('This is a test\n')
f.tell() возвращает текущую позицию в файле в байтах от начала файла .
Для ее изменения , используйте "f.seek(offset, from_what)".
from_what =0 означает начало файла .
>>> f = open('/tmp/workfile', 'r+')
>>> f.write('0123456789abcdef')
>>> f.seek(5) # Go to the 6th byte in the file
>>> f.read(1)
'5'
>>> f.seek(-3, 2) # Go to the 3rd byte before the end
>>> f.read(1)
'd'
Для закрытия файла вызывайте f.close() .
>>> f.close()
>>> f.read()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: I/O operation on closed file
Файловые обьекты имеют дополнительные методы - isatty() and truncate() , редко используемые .
В питоне есть стандартный модуль pickle, который конвертирует любой
обьект питона в строковое представление , а также выполняет обратное представление .
Строковое представление обьекта может быть записано в файл .
Если имеется обьект x , и файловый обьект f который открыт на запись ,
записать обьект в файл можно так :
Прочитать обьект из файла :
|
Елена | Здравствуйте! Можно ли с поомщью Питона считывать информацию с порта ISA? Как это делается? 2007-07-18 21:55:22 | Яковлев Се� | Говорят , вот тут что-то есть про работу с портами:
http://www.hare.demon.co.uk/ioport/ioport.html
Там можно найти пакет , с которым можно работать в стиле :
import ioport
ioport.ioperm(0x3bc, 1, 1)
ioport.outb(0x01, 0x3bc) 2007-07-19 21:32:13 | |
|