Язык программирования Python
Язык Python часто позволяет создавать более короткие и красивые решения. Например, при написании решении задач на языке Python не требуется самостоятельно реализовывать "длинную" арифметику.
Цель этого урока - дать вам начальные данные о языке Python в достаточной мере для решения на нём задач (создания консольных приложений с вводом-выводом при помощи текстовых файлов).
Преимущества и недостатки языка Python
Преимущества:
- Встроенная поддержка "длинной арифметики", комплексных чисел, списков, словарей, стеков, очередей и т.д.
- Кроссплатформенность (программы можно писать и выполнять в Windows / Linux / MacOS / Android и т.д.)
- Поддержка всех кодировок (например UTF-8)
- Большое количество библиотек на все случаи (HTTP и FTP протоколы, работа с сетью, работа с изображениями и т.д.)
- Интерпретируемый язык (можно менять код "на лету"). Удобно писать служебные скрипты.
- Сборщик мусора позволяет не беспокоиться об освобождении памяти.
- Python сравнительно прост в изучении и позволяет выражать алгоритмы кратко и просто.
Недостатки:
- Низкая скорость выполнения (причины: интерпретация, динамическая типизация) по сравнению с Delphi, C/C++, C#, Java.
- Отсутствие библиотек для создания "родных" интерфейсов для Windows (для олимпиадных задач интерфейсы и не нужны).
Установка интерпретатора Python
Официальный сайт: http://www.python.org
Установка под Linux: обычно Python входит в дистрибутив и устанавливается при установке Linux. Установить в любой момент можно командой: sudo apt-get install python
Установка под Windows:
- Скачать на странице http://www.python.org/download/ версию для своей операционной системы
- Запустить PythonXXX.msi и пройти процесс установки (по умолчанию используется каталог C:\PythonXXX). XXX - Номер версии Python, например 26 или 33.
Запуск в режиме калькулятора
Запуск из меню кнопки "Пуск"
Можно запустить из командной строки набрав, например: C:\Python33\python.exe (для версии 3.3)
Работа с Python в режиме калькулятора
Из приведённого на картинке примера видно что:
- Python поддерживает длинную арифметику (
2**30
- это 2 в 30-ой степени, а2**200
— это 2 в 200-ой степени). - Можно обменять значениями переменные в одну строку:
x, y = y, x
- Легко создавать массивы заполненные нужными нам значениями.
[0]*10
— создание массива из 10 нулей. - Python можно использовать как мощный и гибкий калькулятор.
Среда разработки для Python
При использовании среды разработки обратная связь становится более короткой, программист "раньше" видит где он ошибся и может обучаться быстрее. Советую всем кто начинает программировать начинать работать в среде разработки (IDE) и только потом учиться использовать компиляцию из командной строки.
IDLE (Integrated DeveLopment Environment) — IDE, которая устанавливается сразу вместе с Python:
Запуск программы на выполнение — F5.
Среда разработки от компании JetBrains: PyCharm http://www.jetbrains.com/pycharm/
Редактор Notepad++
Для работы с текстом программы можно использовать любой текстовый редактор. Удобнее, если в редакторе есть подсветка синтаксиса. Notepad++ позиционируется как замена стандартному Блокноту (Notepad) в Windows с большими возможностями (прежде всего подсветкой синтаксиса для различных языков программирования).
Загрузить можно с сайта: http://notepad-plus-plus.org/download
Первая программа на Python
Решение задачи "A+B" с вводом из файла sum.in и выводом в файл sum.out.
import sys sys.stdin = open("sum.in") # Закомментируйте эту строку для ввода с клавиатуры sys.stdout = open("sum.out", "w") # Закомментрируйте эту строку для вывода на экран A, B = int(input()), int(input()) # Вводим 2 целых A и B (они в разных строках) print(A + B)
Типы данных в языке Python
- Числа:
- Целые:
2, 4, 99, 234789078743
- Действительные (с плавающей точкой):
2.3, 6.767, 6.67e-11
- Целые:
- Логический — значения могут принимать
True
(истина) илиFalse
(ложь) — результат проверки условия. - Списки (list) — аналог массивов.
- Кортежи (tuple) — неизменяемые списки.
- Наборы (set) — неупорядоченные наборы значений.
- Словари (dict) — ассоциативные массивы, наборы пар ключ-значение.
- Строки: "Hello world"
- ...это ещё не все...
Демонстрация работы различных типов данных:
Понятие переменной, объекта, ссылки, семантика (значение) оператора присваивания
# Отличия переменной, объекта и ссылки # Переменная присваивается "по значению" a = 3 b = a b = 4 print('a = ', a, ' b = ', b) # a = 3 b = 4, переменная a не изменилась после изменения b # Экземпляры классов присваиваются "по ссылке" class MyClass: field = 1 # Создали класс MyClass с одним полем field a = MyClass() a.field = 3 b = MyClass() b = a # Теперь b и a ссылаются на один и тот же объект b.field = 4 print('a.field = ', a.field, ' b.field = ', b.field) # a.field = 4 b.field = 4
print('2. Операторы управления потоком вычислений') # if - условный оператор if (3 > 2) or (1==2) and (3==1+2): # Условие print("3 > 2") # При выполнении условия else: # Необязательный else print("xxx") # Если условие не выполняется # while - цикл с предусловием i = 23 # Задаём значение переменной while i > 0: # Пока больше 0 print(i), # Печатаем в строку i /= 2 # Деление нацело print() # Переводим на новую строку. Получилось: 23 11 5 2 1 # for - обработка множества значений for str in ['first string', 'second', 'third']: print(str) for i in range(1999,2010): print(i), # Получилось: 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 print('3. Функции, определение и вызов функций, формальные и актуальные параметры, рекурсия') # Определение рекурсивной функции вычисления факториала def Factorial(n): # Барьерное условие. Ограничивает область применимости функции # "Мёртвые программы не лгут!" assert n > 0 if n == 1: return 1 else: return n * Factorial(n - 1) # print Factorial(-1) # При вызове будет ошибка с выводом всей # последовательность # Факториал при помощи тернарного оператора в Python def Factorial2(n): return 1 if n == 1 else n * Factorial(n - 1) # (Что-то) если (условие) иначе (что-то другое) # В С/C++: (условие) ? (что-то) : (что-то другое) # Пример вызова обеих функций print("3! = ", Factorial(3), " ", Factorial2(3)) # Генератор # 1 1 2 3 5 8 13 def fibonacci(max): # генератор (а не функция, т.к. оператор return заменён на yield) a, b = 0, 1 while a < max: yield a # return a, + запоминаем место рестарта для следующего вызова a, b = b, a + b # параллельное присваивание, которое выполняется одновременно и параллельно for n in fibonacci(100): # используем генератор fibonacci() как итератор print(n, end=' ') # печатаем все числа Фибоначчи меньшие 100 через пробел print() # Вычисление наименьшего общего делителя, % - деление по модулю (mod) def GCD(a, b): return a if b == 0 else GCD(b, a % b) print("GCD(30, 45) = ", GCD(30, 45)) # Результат: GCD(30, 45) = 15 print("4. Представление чисел в языке Python, операции над числами") from cmath import sin, sqrt from math import * # Подключаем функции библиотеки math print(2**100) # возведение 2 в степень 100 print(sin(pi * 0.5)) # вычисление синуса от половины пи print(3.23e10) # Экспоненциальная форма записи чисел print("Python работает с комплексными числами") x = 1 + 2j # целое число и мнимое число print(x * 2) print("Решим квадратное уравнение x**2 + 1 = 0 с комплексными корнями") a, b, c = 1, 0, 1 D = b*b - 4*a*c dd = ((-sqrt(D), sqrt(D)) if D > 0 else (-1j * sqrt(-D), 1j * sqrt(-D))) x = [(-b+d)/2*a for d in dd] print(x) i = 1 for c in "Привет!": print(i, c) i += 1 print("Привет!") print("5. Представление строк в языке Python, основные операции") str = "String " + '2' print(str, ' ', str.upper(), ' ', str.lower(), ' ', str.center(20)) print(str.count('t')) # Количество букв t в строке # Основные структуры данных языка Python: # списки (lists), тюплы (tuples), словари (dictionaries, dicts). a = [1, 2, "a"] # список b = (1, 2, "a") # кортеж, тюплы (tuples) c = {'a': 1, 'b': 'B'} # словарь l = ['A', 'B', 'C', 'D', 'E'] # Исходный список print("срез от нулевого до второго промежутка ", l[1:5]) # ['A', 'B'] print("срез от второго до второго с конца элемента", l[1:-2]) # ['B', 'C'] print("каждый второй элемент начиная с первого", l[1::2]) # ['B', 'D'] print("все элементы в обратном порядке", l[::-1]) # ['E', 'D', 'C', 'B', 'A'] tuple = (1, 3, 2, "a") # кортеж, тюпл (tuple) print(type(tuple), ' ', tuple) #(1, 3, 2, 'a') for i in tuple: print(i), # 1 3 2 a t = 12345, 54321, 'hello!' # tuple packing print(t) # (12345, 54321, 'hello!')
Вычисление Наибольшего Общего Делителя (НОД) и Наименьшего Общего Кратного (НОК)
# Наибольший общий делитель (НОД) - Greatest Common Divisor def GCD(x, y): return x if y == 0 else GCD(y, x%y) # Наименьшее общее кратное (НОК) НОК(x, y) = x*y/НОД(x, y) - Least Common Multiple def LCM(x, y): return x*y / GCD(x, y) print(GCD(10,15)) print(LCM(10,15)) print(LCM(10,0)) print(LCM(0,30)) print(LCM(60,144))
Найти минимум и максимум в массиве:
A = [100, 34, 678] print("Количество элементов в массиве:",len(A)) print("Минимум:",min(A)) print("Максимум:",max(A))
Различные реализации вставки элемента в отсортированный массив так чтобы он остался отсортированным:
# Вставка элемента в отсортированный массив # так чтобы он оставался отсортированным # 1. Через insert/append def Insert1(b, value): # В функцию передаётся исходный массив b и значение value c = list(b) # Делаем копию списка for i, x in enumerate(b): # Пробегаем по исходному списку if x > value: # Если нашли элемент больше заданного c.insert(i, value) # Добавляем перед ним заданный return c # Возвращаем изменённый список c.append(value) # Если мы так и не нашли заданный элемент, добавляем значение в конец return c # возвращаем новый массив # 2. Используя срезы def Insert2(b, value): for i, x in enumerate(b): # i - индекс в массиве, x - значение if x > value: return b[:i] + [value] + b[i:] # Слияние 3-х массивов return b + [value] # 3. Двоичный поиск (последнего числа меньшего value) def Insert3(b, value): min, max = 0, len(b) while max - min > 0: m = (min + max) // 2 # Делим отрезок пополам if b[m] > value: max = m else: min = m + 1 return b[:max] + [value] + b[max:] # 4. Используя библиотеку bisect - двоичный поиск и вставка def Insert4(b, value): from _bisect import insort l = list(b) insort(l, value) return l # 5. Добавление путем создания нового списка (поэлементно) def Insert5(b, value): p = [] inserted = False for x in b: if x > value and not inserted: p.append(value) inserted = True p.append(x) if not inserted: p.append(value) return p # Проверка, что все функции работают как надо (простейший модульный тест) assert Insert3([11], 10) == [10, 11] assert Insert3([], 10) == [10] assert Insert3([3], 10) == [3, 10] assert Insert3([3, 13], 10) == [3, 10, 13] assert Insert3([2, 6, 8], 10) == [2, 6, 8, 10] assert Insert3([2, 6, 8], 7) == [2, 6, 7, 8] assert Insert3([2, 6, 8], 5) == [2, 5, 6, 8] assert Insert3([2, 6, 8], 3) == [2, 3, 6, 8] assert Insert3([2, 6, 8], 1) == [1, 2, 6, 8] b = [2, 6, 8, 14, 15, 20] assert Insert3(b, 10) == [2, 6, 8, 10, 14, 15, 20] assert Insert3(b, 7) == [2, 6, 7, 8, 14, 15, 20] assert Insert3(b, 5) == [2, 5, 6, 8, 14, 15, 20] assert Insert3(b, 1) == [1, 2, 6, 8, 14, 15, 20] assert Insert1([11], 10) == [10, 11] assert Insert1([], 10) == [10] assert Insert1([3], 10) == [3, 10] assert Insert1([3, 13], 10) == [3, 10, 13] assert Insert1([2, 6, 8], 10) == [2, 6, 8, 10] assert Insert1([2, 6, 8], 7) == [2, 6, 7, 8] assert Insert1([2, 6, 8], 5) == [2, 5, 6, 8] assert Insert1([2, 6, 8], 3) == [2, 3, 6, 8] assert Insert1([2, 6, 8], 1) == [1, 2, 6, 8] assert Insert2([11], 10) == [10, 11] assert Insert2([], 10) == [10] assert Insert2([3], 10) == [3, 10] assert Insert2([3, 13], 10) == [3, 10, 13] assert Insert2([2, 6, 8], 10) == [2, 6, 8, 10] assert Insert2([2, 6, 8], 7) == [2, 6, 7, 8] assert Insert2([2, 6, 8], 5) == [2, 5, 6, 8] assert Insert2([2, 6, 8], 3) == [2, 3, 6, 8] assert Insert2([2, 6, 8], 1) == [1, 2, 6, 8] assert Insert5([11], 10) == [10, 11] assert Insert5([], 10) == [10] assert Insert5([3], 10) == [3, 10] assert Insert5([3, 13], 10) == [3, 10, 13] assert Insert5([2, 6, 8], 10) == [2, 6, 8, 10] assert Insert5([2, 6, 8], 7) == [2, 6, 7, 8] assert Insert5([2, 6, 8], 5) == [2, 5, 6, 8] assert Insert5([2, 6, 8], 3) == [2, 3, 6, 8] assert Insert5([2, 6, 8], 1) == [1, 2, 6, 8] print(b)
# Дан массив с различными элементами. Найти количество положительных элементов, расположенных между минимальным и максимальным элементами. b = [12, 6, -2, 8, -5, 13, -34, 1, -4] max = b[0] min = b[0] for x in b: if x > max: max = x if x < min: min = x
Замена отрицательных элементов массива нулями при помощи генератора:
# Замена отрицательные элементы массива нулями b = [12, 6, -2, 8, -5, 13, -34, 1, -4] p = [0 if x < 0 else x for x in b] print(p)
Даны массивы А и В. Вычислить суммы соответствующих (по индексу) элементов массивов.
A = [28, 15, 4, -5, 6] B = [3, 10, 1, -4, -8] for k, v in enumerate(A): # k - индекс в массиве, v - значение в массиве A print(A[k] + B[k], end=' ') print()
Дано произвольное значение b и произвольный массив G. Найти сумму элементов массива G, меньших заданного b.
b = 6 G = [5,6,71,3,1,3] print(sum(x for x in G if x < b))
Работа со списками (list)
# Пример со списками и словарями l = [2,3,36,4] # Добавление элемента в конец списка l.append(56) # Вставка элемента в середину списка l.insert(3, 999) # Вставить элемент 999 после 3-его элемента списка print(l) # l[6] = 10 # Шестого элемента нет => Будет ошибка
Работа со словарями (dict)
# Создаём словарь d = {} d[23] = 67 print(d) # {23: 67} d[5] = 231 print(d) # {5: 231, 23: 67} # Переписываем 23-ий элемент d[23] = 554 d[23462356] = (2,3) d[234656] = "sdfsgd" for k in sorted(d.keys()): print("d[%s] = %s" % (k, d[k])) print(d) b = [3,2,4] c = list(b) b.append(55) print('b = ', b) print('c = ', c) class Test: value = 1 a = Test() a.value = 2 b = a b.value = 3 print('a = ', a.value) print('b = ', b.value)
Чтение и запись файлов в Python
Пример 1. Читаем размер массива, сам массив, сортируем и выводим.
import sys # Подключаем библиотеку для перенаправления потока sys.stdin = open("sort.in") # Закомментируйте эту строку для ввода с клавиатуры sys.stdout = open("sort.out", "w") # Закомментрируйте эту строку для вывода на экран N = int(input()) # Вводим количество элементов A = [int(x) for x in input().split()] # Вводим сам массив # input - ввод строки, split - деление, int - приведение к целым A.sort() # Сортировка for a in A: print(a), # Вывод отсортированного массива в одну строку разделяя числа пробелами
Пример входного файла sort.in:
13 4 3 8 9 1 32 4 3 2 2 65 4 3
Пример выходного файла sort.out:
1 2 2 3 3 3 4 4 4 8 9 32 65
Стандартные алгоритмы в Python
Классы
Массивы и срезы
# Массив a = ['a','b','c','d','e','f'] # 0 1 2 3 4 5 < Индексы print (a[0]) # Печатаем первый элемент print (a[1]) # Печатаем второй элемент print (a[-1]) # Печатаем последний элемент print (a[0:-1]) # Весь массив без последнего элемента print (a[:-1]) # Весь массив без последнего элемента print (a[0:-1:2]) # Весь массив без последнего элемента через 2 элемента del a[5] # Удаление элемента с индексом 5 del a[1:5] # Удаление с 1-ого (включительно) до 4-го (включительно)
Ссылки и значения в Python
b = a # В b теперь ссылка на a b[0] = 4 print(a[0], b[0]) # Напечатается "4 4", потому что a и b ссылаются на один и тот же список M = [[0]*n]*m # Пытаемся создать 2-х мерный массив M[0][0] = 4 print(M[1][0]) # Выводится тоже 4, а не 0, так как M содержит m одинаковых списков # Правильное создание 2-х мерного массива M = [[0] * n for k in range(m)]
Определение своей функции
def my_function(x): # my_function - имя функции # Определение функции return 2*x # Вызов функции y = my_function(x)
Тернарный оператор
# Тернарный оператор: следующие конструкции дают одинаковый результат: if условие: x = a else: x = b x = a if условие else b
Стандартные функции для обработки массивов
sum([2, 3, 4]) # Сумма элементов в этом списке max([3, 5, 2]) # Максимум min([3, 5, 2]) # Минимум
l = [[1, 2], [3, 4]] # Распаковка кортежей работает и в цикле for for a, b in l: print(a, b) # Часто в теле цикла нужен и элемент и индекс. Программисты на Delphi/C обычно пишут так: for i in range(len(l)): ... используем l[i] ... # Лучше записать так: for i, e in enumerate(l): ... используем и i, и e ...
Рекомендации по офомлению кода
- Переменная должна иметь название, которое даёт понять, для чего она предназначена
-
Как записывать названия:
my_var
(илиmyVar
) — для переменныхMyType
— для названий своих типов данныхMY_CONSTANT
— для констант (пример:RED = 0
)
-
Отступы в арифметических выражениях ставим обычно вокруг операций с меньшим приоритетом:
D = b*b - 4*a*c
. Вокруг=
и операторов сравнения ставить всегда. - После запятой всегда ставим пробел. Перед запятой и вокруг скобок — никогда.
Если надо разбить строку на несколько, пишем все в один столбик:
print('a =', a, 'b =', b)
Различные приёмы
a = [5, 4, 5, 6] a.count(5) # Посчитаем количество 5-ок в списке a # Если хотим получить индексы всех 5-к, используем генератор списка: print([i for i, e in enumerate(a) if e == 5]) # Надо перечислить строки через запятую: print(", ".join(a)) # Функция str преобразует строку в число s = str(4)
Функциональное программирование
Функциональное программирование является одной из парадигм, поддерживаемых языком программирования Python. Основными предпосылками для полноценного функционального программирования в Python являются: функции высших порядков, развитые средства обработки списков, рекурсия, возможность организации ленивых вычислений. Элементы функционального программирования в Python могут быть полезны любому программисту, так как позволяют гармонично сочетать выразительную мощность этого подхода с другими подходами.
Ссылки