{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# язык программирования Python\n", "## часть I - введение\n", "\n", "автор: **Дьяконов Александр www.dyakonov.org**\n", "\n", "**для поддержки курсов автора, в частности https://github.com/Dyakonov/IML**\n", "\n", "\n", "##### материал частично основан на...\n", "\n", "* *Bruce Eckel* **Python 3 Patterns, Recipes and Idioms**\n", "* *Никита Лесников* **Беглый обзор внутренностей Python** // slideshare\n", "* *Сергей Лебедев* **Лекции по языку Питон** // youtube, канал \"Computer Science Center\"\n", "* Learn X in Y minutes https://learnxinyminutes.com/docs/python/\n", "* *Дэн Бейдер* **Чистый Python. Тонкости программирования для профи**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Python (\"питон\" или \"пайтон\")** в честь комедийных серий BBC \"Летающий цирк Монти-Пайтона\"\n", "\n", "создатель: голландец Гвидо ван Россум (Guido van Rossum) в 1991 году\n", "\n", "* интерпретируемый\n", "* объектно-ориентированный\n", "* высокоуровневый язык\n", "* встроенные высокоуровневые структуры данных\n", "* динамическая типизация\n", "* синтаксис прост в изучении\n", "* поддержка модулей и пакетов (большинство библиотек бесплатны)\n", "* универсальный\n", "* интеграция с другими языками (C, C++, Java)\n", "\n", "Поддерживаемые парадигмы:\n", "\n", "* императивное (процедурный, структурный, модульный подходы) программирование\n", "* объектно-ориентированное программирование\n", "* функциональное программирование\n", "\n", "Ветки (несовмесимые) языка:\n", "\n", "* Python 2.x\n", "* Python 3.x (сейчас уже почти все перешли на 3)\n", "\n", "Особенности:\n", "\n", "* вместо отступов - скобки\n", "* индексация с 0 (в отличиии от R, Matlab)\n", "\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ответ = 3\n" ] }, { "data": { "text/plain": [ "'\\nнет\\nмногострочных\\nкомментариев\\n'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# ---\n", "print ('ответ =', \\\n", " 3) # комментарий\n", "\n", "\"\"\"\n", "нет\n", "многострочных\n", "комментариев\n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## условный оператор, функция" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 0, -1)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# функция\n", "# if - условный оператор\n", "def sgn(x):\n", " \"\"\"\n", " функция 'знак числа'\n", " +1 - для положительного аргумента\n", " -1 - для отрицательного аргумента\n", " 0 - для нуля\n", " Пример: sgn(-2.1) = -1\n", " \"\"\"\n", " if x > 0:\n", " a = +1\n", " elif x < 0:\n", " a = -1\n", " else:\n", " a = 0\n", " return a\n", "\n", "sgn(2.1), sgn(0), sgn(-2)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function sgn in module __main__:\n", "\n", "sgn(x)\n", " функция 'знак числа'\n", " +1 - для положительного аргумента\n", " -1 - для отрицательного аргумента\n", " 0 - для нуля\n", " Пример: sgn(-2.1) = -1\n", "\n" ] } ], "source": [ "# вывод по команде help\n", "help (sgn)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'nonzero'" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# ещё вариант if-a\n", "\n", "x = 0.01\n", "\"nonzero\" if x != 0 else \"zero\"" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function sgn in module __main__:\n", "\n", "sgn(x)\n", " функция 'знак числа'\n", " +1 - для положительного аргумента\n", " -1 - для отрицательного аргумента\n", " 0 - для нуля\n", " Пример: sgn(-2.1) = -1\n", "\n" ] } ], "source": [ "# помощь по функции\n", "help (sgn)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## циклы, вывод" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Введите строку:abc\n", "abc\n", "b\n" ] } ], "source": [ "# цикл\n", "# строки\n", "\n", "# s = \"1234567\"\n", "s = input(\"Введите строку:\")\n", "while s: # s != \"\":\n", " print (s)\n", " s = s[1:-1]\n", " \n", "# цикла repeat - нет!" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3 \n", "2 4 6 \n", "3 6 9 \n" ] } ], "source": [ "# for - цикл\n", "for i in range(1, 4):\n", " s = \"\"\n", " for j in range(1, 4):\n", " s += (\"%i \" % (i * j)) \n", " #print (\"%i\" % (i*j),)\n", " print (s)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 a\n", "10 b\n", "20 a\n", "20 b\n" ] } ], "source": [ "# можно много по чему итерироваться\n", "for i in [10, 20]:\n", " for j in 'ab':\n", " print (i, j)\n", " \n", "# нет явного счётчика - об этом позже" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{2, 3, 5, 7, 11, 13, 17, 19}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Пример решения задачи на Питоне\n", "\n", "import math\n", "\n", "def primes(N):\n", " \"\"\"Возвращает все простые от 2 до N\"\"\"\n", " sieve = set(range(2, N))\n", " for i in range(2, round(math.sqrt(N))):\n", " if i in sieve:\n", " sieve -= set(range(2 * i, N, i))\n", " return sieve\n", "\n", "primes(20)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "continue # нет примера\n", "break # нет примера" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## jupiter notebook" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[1, 2, 3]" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "_[0] # предыдущая ячейка" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(__) # пред-предыдущая ячейка " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Out[7] # конкретная ячейка" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "u'C:\\\\tmp\\\\notebooks'" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pwd # unix-dos-команды" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Специфика питона" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "11\n" ] } ], "source": [ "i, j = 1, 2\n", "print(\"%i\" % (i * j))\n", "print(\"%i\" % i * j) # % и * имеют один приоритет! Поэтому ответ '1'*2" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-1 2 0.5\n", "onetwoonetwoonetwo\n" ] } ], "source": [ "i = j = k = 1 # одновременное присвоение\n", "i -= 2 # аналоги +=\n", "j *= 2\n", "k /=2\n", "print (i, j, k)\n", "\n", "s = 'one'\n", "s += 'two'\n", "s *=3\n", "print (s)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from модуль import *\n", "# лучше так не делать!" ] }, { "cell_type": "code", "execution_count": 135, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on built-in function len in module builtins:\n", "\n", "len(obj, /)\n", " Return the number of items in a container.\n", "\n" ] } ], "source": [ "# помощь\n", "help(len)" ] }, { "cell_type": "code", "execution_count": 136, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Return the number of items in a container.\n" ] } ], "source": [ "# помощь\n", "print (len.__doc__)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hash: 6612913437847469369 6612913437847469369 6612913437847469369\n", "hash: 139905333472760 139905333472760 139905333472760\n" ] } ], "source": [ "s1 = \"abcde\"\n", "s2 = \"abcde\"\n", "s3 = \"ab\" + \"cd\" + \"e\"\n", "\n", "print (\"hash:\", hash(s1), hash(s2), hash(s3))\n", "\n", "print (\"hash:\", id(s1), id(s2), id(s3))\n", "# а раньше id(s1) = id(s2) != id(s3)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "#--\n", "x = None # ничего\n", "\n", "if x is None: # или x is not None\n", " pass # ничего не делать\n", "else:\n", " print (x)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "False\n" ] } ], "source": [ "# is - используется только для None\n", "# интерпретатор кэширует числа от -5 до 256 - для каждого числа есть лишь один объект\n", "print (int(\"-5\") is -5)\n", "print (int(\"-6\") is -6)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "True\n" ] } ], "source": [ "a = 257\n", "b = 257\n", "print (a is b)\n", "\n", "def f(): # умный интерпретатор сделает это одним объектом\n", " a = 257\n", " b = 257\n", " print (a is b)\n", " \n", "f()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "True\n" ] } ], "source": [ "print (1000+0 is 1000+0)\n", "print (1000 is 1000)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 5 0 LOAD_FAST 0 (x)\n", " 3 LOAD_CONST 1 (1)\n", " 6 BINARY_ADD\n", " 7 LOAD_FAST 0 (x)\n", " 10 LOAD_CONST 1 (1)\n", " 13 BINARY_SUBTRACT\n", " 14 BUILD_TUPLE 2\n", " 17 RETURN_VALUE\n" ] } ], "source": [ "# байткод\n", "import dis\n", "\n", "def myf(x):\n", " return(x+1,x-1)\n", "\n", "dis.dis(myf)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "17 ns ± 1.68 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n", "12.9 ns ± 0.0339 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)\n" ] } ], "source": [ "%timeit x, y = 1, 2\n", "\n", "# второй вариант быстрее\n", "%timeit x = 1; y = 2\n", "\n", "#timeit - на время измерений отключается сборщик мусора" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6.46 ns ± 0.213 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)\n", "6.79 ns ± 0.967 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)\n" ] } ], "source": [ "x = 10\n", "\n", "%timeit \"x = x * 2\"\n", "\n", "# второй вариант чуть быстрее\n", "%timeit \"x = x + x\"" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6.45 ns ± 0.162 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)\n", "6.39 ns ± 0.0943 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)\n" ] } ], "source": [ "x = 10\n", "\n", "%timeit \"x = x ** 2\"\n", "\n", "# второй вариант чуть быстрее\n", "%timeit \"x = x * x\"" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6.94 ns ± 0.104 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)\n", "6.37 ns ± 0.015 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)\n" ] } ], "source": [ "x = 10\n", "%timeit \"a = x > 1.0\"\n", "\n", "# второй вариант чуть быстрее - не будет приведения типов\n", "x = 10.\n", "%timeit \"a = x > 1.0\"" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one+two\n", "one+two\n", "one+two\n", "one+two\n", "one+two\n", "104 ns ± 23.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n", "134 ns ± 0.809 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n", "156 ns ± 0.279 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n", "106 ns ± 0.202 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n", "9.78 ns ± 1.38 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)\n" ] } ], "source": [ "x = \"one\"\n", "y = \"two\"\n", "\n", "print (x + '+' + y)\n", "print (\"\".join((x, '+', y)))\n", "print (\"%s+%s\" % (x, y))\n", "print (\"{0}+{1}\".format(x, y))\n", "print (f\"{x}+{y}\")\n", "\n", "%timeit x + '+' + y\n", "%timeit \"\".join((x, '+', y))\n", "%timeit \"%s+%s\" % (x, y)\n", "%timeit \"{0}+{1}\".format(x, y)\n", "%timeit f\"{x}+{y}\"" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1000 loops, best of 3: 675 µs per loop\n", "1000 loops, best of 3: 440 µs per loop\n" ] } ], "source": [ "def f():\n", " l = []\n", " for i in range(10000):\n", " l.append(i) # будет искать этот метод... (в хеш-таблице...)\n", " return (l)\n", " \n", "%timeit f()\n", "\n", "# этот вариант быстрее!\n", "def g():\n", " l = []\n", " li = l.append # сразу сообщим функцию - чтобы не искать в цикле\n", " for i in range(10000):\n", " li(i)\n", " return (l)\n", "\n", "%timeit g()" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "g\n", "g\n", "g\n", "g\n", "g\n", "g\n", "g\n", "True\n" ] } ], "source": [ "# неожиданное поведение... не увлекайтесь функциональным программированием\n", "l = [lambda: x for x in \"abcdefg\"]\n", "for r in l:\n", " print (r())\n", " \n", "# объяснение - особенности лямбда-функций\n", "print (id(lambda: 1) == id(lambda: 2))" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The Zen of Python, by Tim Peters\n", "\n", "Beautiful is better than ugly.\n", "Explicit is better than implicit.\n", "Simple is better than complex.\n", "Complex is better than complicated.\n", "Flat is better than nested.\n", "Sparse is better than dense.\n", "Readability counts.\n", "Special cases aren't special enough to break the rules.\n", "Although practicality beats purity.\n", "Errors should never pass silently.\n", "Unless explicitly silenced.\n", "In the face of ambiguity, refuse the temptation to guess.\n", "There should be one-- and preferably only one --obvious way to do it.\n", "Although that way may not be obvious at first unless you're Dutch.\n", "Now is better than never.\n", "Although never is often better than *right* now.\n", "If the implementation is hard to explain, it's a bad idea.\n", "If the implementation is easy to explain, it may be a good idea.\n", "Namespaces are one honking great idea -- let's do more of those!\n" ] } ], "source": [ "import this" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## PEP8\n", "стилистические рекомендации по оформлению кода\n", "\n", "* отступ - 4 пробела\n", "* длина строки <= 79 символов\n", "* переменные: var_recommended\n", "* константы: CONST_RECOMMENDED" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = -0.1\n", "b = (x / 2) + 1\n", "lst = ['one','two'\n", " 'three'\n", " ]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## булева логика" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "True\n", "True\n", "False\n", "True\n", "False\n" ] } ], "source": [ "x, y = True, False\n", "\n", "print (x and y)\n", "print (x or y)\n", "print (not y)\n", "print (x and y)\n", "print ((1 == 2) | (2 == 2))\n", "print ((1 < 2) & (2 != 2))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "# приведение типов\n", "print (bool('True') == bool(1))" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "empty-1\n" ] } ], "source": [ "# проверка списка на пустоту\n", "lst = []\n", "\n", "if not lst:\n", " print ('empty-1')\n", " \n", "lst = [False]\n", "\n", "if not lst:\n", " print ('empty-2')\n", " \n", "lst = [True]\n", "\n", "if not lst:\n", " print ('empty-3')" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "False\n", "четыре\n", "четыре\n" ] } ], "source": [ "print(1 < 2 < 3 < 4)\n", "print(1 < 3 < 3 < 4)\n", "\n", "x = 4\n", "\n", "if 3 < x < 5: # можно без скобок\n", " print ('четыре')\n", "\n", "# или\n", "if 3 < x and x < 5:\n", " print ('четыре')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ввод значений\n", "лучше не применять" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "01\n", "010101\n" ] } ], "source": [ "a = input()\n", "print (a*3) # будет строкой!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## исключения\n", "\n", "* Exception - класс, от которого должны наследоваться все исключения\n", "* AssertionError - ошибка assert\n", "* ImportError - ошибка import\n", "* NameError - не найдена переменная\n", "* AttributeError - читаем/пишем несуществующий атрибут\n", "* KeyError / IndexError - в контейнере нет элемента по указанному ключу / индексу\n", "* TypeError - несоответствие типов\n", "\n", "см. https://docs.python.org/3/library/exceptions.html\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.5\n", "Моя ошибка\n", "Последние действия\n" ] } ], "source": [ "# исключения\n", "\n", "class MyError(Exception): # Exception - класс, от которого должны наследоваться все исключения\n", " pass\n", "\n", "try:\n", " a = 1\n", " b = 2\n", " print (a / b)\n", " raise (MyError) # поднимаем исключение\n", "# else: не работает! и в Python3\n", "# print (\"Не было исключения\")\n", "except ZeroDivisionError: # принимаем исключение\n", " print (\"Деление на 0\")\n", "except KeyboardInterrupt:\n", " print (\"Прерывание с клавиатуры\")\n", "except (MyError):\n", " print (\"Моя ошибка\")\n", "except:\n", " print (\"Ошибка\")\n", "finally:\n", " print (\"Последние действия\")\n", " # тут можно, например, закрыть файл" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('division by zero',)\n", "выполнение программы продолжается\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " File \"\", line 5, in \n", " 1 / 0\n" ] } ], "source": [ "# Обработка любого исключения\n", "import traceback\n", "\n", "try:\n", " 1 / 0\n", "except Exception as e:\n", " print (e.args) # переданные аргументы\n", " traceback.print_tb(e.__traceback__) # информация о стеке вызовов на момент исключения\n", " # pass\n", "\n", "print ('выполнение программы продолжается')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# менеджер контекста\n", "\n", "with resource_1() as r1, \\\n", " resource_2() as r2:\n", " do_smth(r1, r2)\n", " \n", "# в случае с файлами - не надо явно закрывать" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "init\n", "enter\n", "working... with m_c-name\n", "exit\n" ] } ], "source": [ "# можно самому написать менеджер контекста\n", "class m_c:\n", " def __init__(self):\n", " print ('init')\n", " # возвращает None\n", " \n", " def __enter__(self):\n", " # тут можно, например, открыть файл\n", " print ('enter')\n", " # возвращаемое значение доступно по имени with ... as NAME:\n", " return ('m_c-name') \n", " \n", " def __exit__(self, *exc_info):\n", " # вызывается в конце\n", " # аргументы:\n", " # - тип исключения\n", " # - исключение\n", " # - объект типа traceback\n", " print ('exit')\n", "\n", "with m_c() as name:\n", " print ('working... with ' + name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## типы чисел\n", "- int - целые\n", "- long - произвольная точность (нет в Python 3)\n", "- float\n", "- complex" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376\n" ] } ], "source": [ "print (2 ** 1000)\n", "# print (2L ** 1000) # не работает\n", "# в третьем int имеет произвольную точность!" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# type(3)\n", "type(2 ** 1000)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\n", "\n" ] } ], "source": [ "print (type(1))\n", "print (type(1.0))\n", "print (type(int(1.0))) # преобразование типов\n", "print (type(-1.2+3.7j + 5))" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n" ] } ], "source": [ "имя = 10 # не рекомендуется\n", "print(имя)\n", "del имя # удаление объекта\n", "# print (имя) - ошибка" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "1\n", "3.3333333333333335\n" ] } ], "source": [ "print(10 // 3) # Python 3 - деление нацело\n", "print(10 % 3) # остаток\n", "\n", "from __future__ import division\n", "print(10 / 3) # в Python 2 - нацело" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## строки\n", "нет понятия символ (-- это одноэлементная строка)\n", "\n", "в Python3 строка - последовательность символов Юникод" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "привет\n", "раз\n", "два\n", "три\n" ] }, { "data": { "text/plain": [ "'раз\\nдва\\nтри'" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = u'\\u043f\\u0440\\u0438\\u0432\\u0435\\u0442'\n", "print(s)\n", "\n", "s2 = \"\"\"раз\n", "два\\nтри\"\"\"\n", "print(s2)\n", "s2" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "привет\n" ] }, { "data": { "text/plain": [ "'привет'" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = '\\u043f\\u0440\\u0438\\u0432\\u0435\\u0442'\n", "print(s)\n", "s" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AB\n", "AAA\n", "AB7\n" ] } ], "source": [ "# операции\n", "print ('A' + 'B') # конкатенация\n", "print ('A' * 3) # повтор\n", "print ('A%s%i' % ('B', 7)) # форматирование" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "string string string string string\n" ] } ], "source": [ "# задание одной и той же строки\n", "\n", "s1 = \"string\"\n", "s2 = 'string'\n", "s3 = \"\"\"string\"\"\"\n", "s4 = 'st' 'rin' 'g' # будет склейка (аналогично операции +)\n", "s5 = 'st' + 'rin' + 'g'\n", "print (s1, s2, s3, s4, s5)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "string string string string True True True\n", "\u0001\u0002 -- \\1\\2\n" ] }, { "data": { "text/plain": [ "'\\\\1\\\\2'" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print (s1, s2, s3, s4, s1 == s2, s1 == s3, s1 == s4)\n", "s4 = '\\1\\2'\n", "s5= r'\\1\\2'\n", "print (s4, '--', s5)\n", "s5" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "000000.333\n", " +0.3333\n", "0.33333 \n", "3.33333e-01\n" ] } ], "source": [ "# форматирование\n", "print('%010.3g' % (1 / 3))\n", "print('%+10.4g' % (1 / 3))\n", "print('%-10.5g' % (1 / 3))\n", "print('%-10.5e' % (1 / 3))" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a=3.3333e-01, b=+0.143, c=0.09090909090909091\n", "a= one, b=14.285714%, c=000.09\n" ] } ], "source": [ "# другой способ форматирования (более гибкий)\n", "\n", "print (\"a={:0.4e}, b={:+2.3f}, c={}\".format(1 / 3, 1 / 7, 1 / 11))\n", "print (\"a={:>5s}, b={:%}, c={:06.2f}\".format('one', 1 / 7, 1 / 11))" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "~~~~a~~~~~\n", "~~~aaa~~~~\n", "~~aaaaa~~~\n" ] } ], "source": [ "# вывод в блоке одной длины\n", "print (\"{:~^10}\".format(\"a\"))\n", "print (\"{:~^10}\".format(\"aaa\"))\n", "print (\"{:~^10}\".format(\"aaaaa\"))" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "int - 12, hex - c, bin - 1100\n", "x=1, y=2, z=4\n" ] } ], "source": [ "# разные форматы чисел\n", "print (\"int - {0:d}, hex - {0:x}, bin - {0:b}\".format(12))\n", "\n", "# можно именовать аргументы и использовать индексы\n", "print (\"x={0[0]}, y={0[1]}, z={z}\".format([1,2], 3, z=4))" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "s str ng\n" ] } ], "source": [ "# индексация\n", "s = 'string'\n", "print (s[0], s[:3], s[-2:])" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one,two,three ['one', 'two', 'three']\n", "one;two;three\n" ] } ], "source": [ "s = 'one,two,three'\n", "s2 = s.split(',') # расщепление в список\n", "print (s, s2)\n", "print (\";\".join(s2)) # объединение через разделитель" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "0\n", "4\n", "False\n", "True\n", "False\n", "False\n", "one,one+two+three\n", "offe,offe\n", "abe,abe\n", "12\n", "ONE,ONE\n", "False\n" ] } ], "source": [ "# методы работы со строками\n", "s = 'one,one'\n", "print (s.count('on')) # подсчёт вхождения подстроки\n", "print (s.find('on')) # поиск подстроки (есть ещё index - с исключениями)\n", "print (s.rfind('on')) # поиск последней подстроки (последнее вхождение)\n", "print (s.isalpha()) # только буквы\n", "print (s.islower()) # только строчные / isupper / istitle / isspace\n", "print (s.isdigit()) # число\n", "print (s.isalnum()) # только буквы и цифры\n", "print (\"+\".join([s,'two','three'])) # соединение через разделитель\n", "print (s.replace('on','off')) # замена подстрок\n", "print (s.translate({ord('o'): 'a', ord('n'): 'b'})) # Python3 множественная замена символов\n", "print (' 12 '.strip()) # удаление первых и последних пробелов, ещё - lstrip, rstrip\n", "print (s.upper()) # в верхний регистр\n", "print ('file.txt'.endswith('.exe')) # startwith" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "One,one\n", "('one', ',', 'one')\n" ] } ], "source": [ "print(s.capitalize()) # первую букву в верхний регистр, ост. - в нижний\n", "\n", "print (s.rpartition(',')) # расщепление по разделителю" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "my string \n", "--my string--\n", " my string\n" ] } ], "source": [ "# выравнивание в блоке фиксированной длины\n", "s = 'my string'\n", "print (s.ljust(13, ' '))\n", "print (s.center(13, '-'))\n", "print (s.rjust(13)) # пробел можно не указывать" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "True\n", "True\n" ] } ], "source": [ "# вхождение подстроки (проверка, а не поиск)\n", "s = \"one,two,three\"\n", "\n", "print ('on' in s)\n", "print ('ab' not in s)\n", "print ('o,' in s)\n" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Байты" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "b'\\x00\\x01\\x08'" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = b\"\\00\\01\\10\"\n", "x" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "b'\\xd1\\x81\\xd1\\x82\\xd1\\x80\\xd0\\xbe\\xd0\\xba\\xd0\\xb0'" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = \"строка\"\n", "s.encode(\"utf-8\")" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'строка'" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = b'\\xd1\\x81\\xd1\\x82\\xd1\\x80\\xd0\\xbe\\xd0\\xba\\xd0\\xb0'\n", "x.decode(\"utf-8\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## кортеж (tuple)\n", "неизменяемый тип" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 1\n" ] } ], "source": [ "a = 1\n", "b = 2\n", "a, b = b, a\n", "print (a, b)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3\n", "1 2 3 4\n", "3\n" ] } ], "source": [ "a, b, c = 1, 2, 3 # это tuple (см. дальше)\n", "print (a, b, c)\n", "\n", "(x, y), (z, t) = [1, 2], [3, 4]\n", "print (x, y, z, t)\n", "\n", "x, (x, x) = 1, (2, 3) # сработает последнее присваивание\n", "print (x)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n" ] } ], "source": [ "a = 1, 2, 3\n", "# a = (1, 2, 3)\n", "# a = tuple((1, 2, 3))\n", "for x in a:\n", " print (x)" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "()" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# пустой кортеж\n", "a = () # раньше (,)\n", "a" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "True\n", "False\n" ] } ], "source": [ "a = (None, True, 2, \"-1\") # м.б. разные типы\n", "\n", "# in - для всех контейнеров\n", "print (2 in a)\n", "print (2.0 in a)\n", "print (-1 in a)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(2,)\n" ] }, { "data": { "text/plain": [ "2" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = (2,) # одноэлементный кортеж\n", "print (x)\n", "\n", "[y] = x # элемент этого кортежа\n", "y" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('Иван', 'Иванов') (22, 'мая', 2001)\n" ] } ], "source": [ "person = (\"Иван\", \"Иванов\", 22, \"мая\", 2001)\n", "NAME, BIRTHDAY = slice(2), slice(2, None)\n", "print (person[NAME], person[BIRTHDAY]) # вместо :2 и 2:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(3, 2, 1)\n", "(3, 2, 1)\n" ] } ], "source": [ "x = (1, 2, 3)\n", "\n", "print(x[::-1])\n", "\n", "print(tuple(reversed(x)))" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3, 4)" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = (1, 2)\n", "y = (3, 4)\n", "x + y # конкатенация" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "False\n", "True\n", "False\n" ] } ], "source": [ "# сравнение (лексикографический порядок)\n", "print ((1, 2) < (1, 3))\n", "print ((1, 2) < (1, 2))\n", "print ((1, 2) < (1, 2, 1))\n", "print ((2,) < (1, 3))" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Person(name='Иван', age=16)" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# именованный кортеж\n", "from collections import namedtuple\n", "\n", "Person = namedtuple(\"Person\", [\"name\", \"age\"])\n", "\n", "p = Person(\"Иван\", age=16)\n", "\n", "p" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## список (list)" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3]\n", "[0, 1, 2]\n", "[0, 1, 2]\n", "['с', 'т', 'р', 'о', 'к', 'а']\n", "[1, 2, 3]\n", "[1, 1, 2]\n" ] } ], "source": [ "print ([1, 2, 3]) # список\n", "print ([x for x in range(3)])\n", "\n", "# преобразование типов\n", "print (list(range(3))) # из генератора\n", "print (list(u'строка')) # из строки\n", "print (list({1, 3, 1, 2})) # из множества\n", "print (list((1, 1, 2))) # из кортежа - меньше скобок нельзя" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "True\n", "[1, 2, 3, 1, 2, 3]\n", "[1, 2, 3, 1, 2, 3]\n", "[1, 2]\n", "[1, 3]\n", "3\n" ] } ], "source": [ "s = [1, 2, 3] # это список\n", "\n", "print (len(s)) # длина списка!\n", "\n", "print (2 in s) # принадлежность списку\n", "\n", "print (s + s) # создаётся новый список!\n", "\n", "print (s * 2) # \"удоение\"\n", "\n", "print (s[:2]) # \"срез\"\n", "\n", "print (s[0:3:2])\n", "\n", "print (max(s)) # максимальный элемент" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[100, 3]" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del s[1] \n", "s[0] = 100\n", "s" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[4, 4]\n", "[4, 4, 2]\n", "[4, 4, 2, 3, 3]\n", "2\n", "2\n", "[3, 3, 2, 4, 4] [4, 4, 2, 3, 3]\n", "[2, 3, 3, 4, 4]\n", "3\n", "[2, 3, 4, 4]\n", "[1, 2, 3, 4, 4]\n", "[1, 2, 3, 4, 5, 4]\n", "[1, 2, 0, 0, 0, 0]\n", "[1, 2, 0]\n" ] } ], "source": [ "s = [4] * 3 # [4, 4, 4]\n", "s.remove(4) # удаление первого вхождения элемента\n", "print(s)\n", "s.append(2) # добавление элемента\n", "print(s)\n", "s.extend([3, 3]) # добавление последовательности\n", "print(s)\n", "print(s.count(4)) # сколько элементов\n", "print(s.index(2)) # индекс элемента (первое вхождение), если не входит - исключение ValueError\n", "s.reverse() # инвертирование\n", "print(s, s[::-1])\n", "s.sort() # сортировка\n", "print(s)\n", "print (s.pop(1)) # возвращает с удалением элемент (по индексу) pop() - последний\n", "print(s)\n", "s.insert(0, 1) # вставка элемента\n", "print(s)\n", "s.insert(-1, 5) # вставка элемента\n", "print(s)\n", "s[-4:] = [0]*4 # вставка элементов\n", "print(s)\n", "# вставка элемента\n", "del s[-3:] # удаление элементов\n", "print(s)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 27]\n" ] } ], "source": [ "# хождение по списку\n", "y = []\n", "for x in [1, 2, 3]:\n", " y.append(x**x)\n", "print (y)" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[0], [0]]\n", "[[1], [1]]\n", "[[2], [2], [2], [2]]\n" ] } ], "source": [ "# при *n не происходит копирования списка!\n", "x = [[0]]*2 # делаем список\n", "print(x)\n", "x[0][0] = 1 # меняем один элемент ... а поменялись оба\n", "print(x)\n", "\n", "x = x + x\n", "x[0][0] = 2 # такой же эффект\n", "print(x)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[1], [0]]" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from copy import copy\n", "x = [copy([0]) for i in range(2)]\n", "x[0][0] = 1\n", "x" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[1], [0]]" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from copy import copy\n", "x = [[0] for i in range(2)]\n", "x[0][0] = 1\n", "x" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-1\n", "deque([0, 1, 2, 3, 4, 5])\n" ] } ], "source": [ "# двусторонняя очередь\n", "from collections import deque\n", "\n", "# добавление / удаление - константное время\n", "q = deque([1,2,3,4])\n", "q.appendleft(0)\n", "q.appendleft(-1)\n", "q.append(5)\n", "print (q.popleft())\n", "print (q)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### индексация" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "[0, 1]\n", "[2, 3, 4, 5]\n", "[0, 1, 2, 3]\n", "[4, 5]\n", "[0, 2]\n", "[0, 3]\n", "[5, 4, 3, 2, 1, 0]\n" ] } ], "source": [ "s = [0, 1, 2, 3, 4, 5]\n", "print(s[2]) # третий! элемент\n", "print(s[:2]) # первые два элемента\n", "print(s[2:]) # после второго\n", "print(s[:-2]) # без двух элементов\n", "print(s[-2:]) # последние два\n", "print(s[0:4:2]) # от : до : шаг\n", "print(s[::3]) # все через шаг\n", "print(s[::-1]) # в обратном порядке" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[-2, -1, 0, 1, 2, 3, 4, 5]\n" ] }, { "data": { "text/plain": [ "[-2, -1, 0, 1, 2, 3, 4, 0.1, 0.2, 5]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# нетривиально!\n", "s = [0, 1, 2, 3, 4, 5]\n", "s[0:0] = [-2, -1]\n", "print(s)\n", "s[-1:0] = [0.1, 0.2]\n", "s" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 3, 4]" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = list(range(5))\n", "del s[1:3] # удаление среза\n", "s" ] }, { "cell_type": "code", "execution_count": 177, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 0, 0, 0, 0, 0]\n", "[[0, 0], [0, 0], [0, 0]]\n" ] } ], "source": [ "# кстати\n", "\n", "print ([0,0] * 3)\n", "\n", "print ([[0,0]] * 3)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# вложенные списки\n", "a = [1, 2, 3]\n", "b = [4, 5, 6]\n", "lst = [1, [a, b]]\n", "\n", "lst[1][0][2]" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'string'" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# контейнер для разнородных элементов\n", "s = [1, 'string', [1,2,3], True]\n", "s[1]" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "t\n", "s\n", "i\n", "l\n" ] } ], "source": [ "# исчерпание списка в цикле\n", "s = list('list')\n", "while s:\n", " print (s.pop())" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "True\n", "False\n" ] } ], "source": [ "print([1, 2] < [1, 3])\n", "print([1, 2] < [1, 2, 1])\n", "print([2] < [1, 3])" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Иван', 'Иванов'] [22, 'мая', 2001]\n" ] } ], "source": [ "person = [\"Иван\", \"Иванов\", 22, \"мая\", 2001]\n", "NAME, BIRTHDAY = slice(2), slice(2, None)\n", "print(person[NAME], person[BIRTHDAY]) # вместо :2 и 2:\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## dict (cловари)\n", "Для хранения (key, value)\n", "Порядок не важен" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'a': 1, 'b': 2}\n", "{'a': 1, 'b': 2}\n", "{'a': 3, 'b': 2, 'd': 2}\n", "{'a': 1, 'b': 2}\n", "dict_keys(['a', 'b'])\n", "dict_values([1, 2])\n", "dict_items([('a', 1), ('b', 2)])\n", "1\n", "0\n", "True\n", "{'b': 2}\n" ] } ], "source": [ "dct = {'a': 1, 'b': 2} # словарь\n", "print (dct)\n", "\n", "dct = dict(a=1, b=2) # другой способ\n", "print (dct)\n", "\n", "dct = dict(dct, a=3, d=2) # добавление к словарю\n", "print (dct)\n", "\n", "dct = dict([('a', 1), ('b', 2)]) # преобразование из списка\n", "print (dct)\n", "\n", "print(dct.keys()) # ключи\n", "\n", "print(dct.values()) # значения\n", "\n", "print(dct.items()) # пары (ключ, значение)\n", "\n", "print (dct['a']) # обращение по ключу (если нет - исключение KeyError)\n", "\n", "print (dct.get('c', 0)) # обращение по ключу со значением по умолчанию (когда ключ не найден)\n", "\n", "print ('a' in dct) # есть ли ключ\n", "\n", "del dct['a'] # удаление по ключу\n", "print (dct)" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'a': True, 'b': '02', 'c': [1, 2, 3]}\n", "{'a': True, 'b': '02', 'c': [1, 2, 3], 'd': 100.0}\n", "{'a': True, 'b': '02', 'c': [1, 2, 3], 'd': 100.0, 'e': 1, 'f': 2}\n", "c = [1, 2, 3]\n", "{'a': True, 'b': '02', 'd': 100.0, 'e': 3, 'f': 4}\n" ] } ], "source": [ "d = dict(a=True, b=\"02\", c=[1, 2, 3]) # можно так создавать\n", "print(d)\n", "d.setdefault('c', 100.0) # попытка добавить значение, если нет\n", "d.setdefault('d', 100.0)\n", "print(d)\n", "d.update(e=1, f=2) # дабавить ещё значений\n", "print(d)\n", "d.update([('e', 3), ('f', 4)]) # дабавить ещё значений - старые значения заменятся на новые\n", "print ('c = ', d.pop('c')) # возвращаем значение и удаляем его из словаря\n", "print (d)\n", "d.clear() # удалить из словаря все значения" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': True, 'b': True, 'c': True}" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dict.fromkeys(\"abc\", True) # словарь со значением по умолчанию" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 1\n", "b 2\n", "0 5\n", "a 1\n", "b 2\n", "0 5\n", "1\n", "2\n", "5\n", "длина словаря = 3\n" ] } ], "source": [ "dct = {'a': 1, 'b': 2}\n", "dct[0] = 5\n", "\n", "for key, val in dct.items(): # цикл по словарю\n", " print (key, val)\n", "\n", "for key in dct.keys(): # цикл по ключам словаря\n", " print (key, dct[key])\n", " \n", "for val in dct.values(): # цикл по значениям словаря\n", " print (val)\n", "\n", "print ('длина словаря = %i' % len(dct)) # количество пар в словаре \n", " " ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 1, 'b': 3, 'c': 4}" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dct = {'a':1, 'b':2}\n", "dct2 = {'b':3, 'c':4}\n", "\n", "dct.update(dct2) # пополнение словаря\n", "dct" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'c': 4, 'a': 1, 'b': 3} {'b': 2, 'a': 1} {'c': 4, 'b': 3}\n", "{'c': 4, 'a': 1, 'b': 3} {'b': 2, 'a': 1} {'c': 4, 'b': 3}\n", "{'c': 4, 'a': 1, 'b': 3} {'b': 2, 'a': 1} {'c': 4, 'b': 3}\n" ] } ], "source": [ "# но если нужно объединить 2 словаря не портя оба...\n", "dct = {'a': 1, 'b': 2}\n", "dct2 = {'b': 3, 'c': 4}\n", "\n", "union = {**dct, **dct2} # Python3-способ\n", "print(union, dct, dct2)\n", "\n", "union = dct.copy() # Python2-способ\n", "union.update(dct2)\n", "print(union, dct, dct2)\n", "\n", "union = dict(dct, **dct2)\n", "print(union, dct, dct2)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 1, 'b': 2, 'c': 3}" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# преобразование типов\n", "a = ['a', 'b', 'c']\n", "b = [1, 2, 3]\n", "dict(zip(a, b))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# вывод словаря с упорядочиванием по значениям\n", "import operator\n", "x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}\n", "sorted_x = sorted(x.items(), key=operator.itemgetter(1))\n", "sorted_x" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 1, 'b': 2, 'c': 3}" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d = {'a': 1, 'b': 2}\n", "if 'c' not in d: # так проверям на не-вхождение\n", " d['c'] = 3\n", "d" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# одно из применений словарей - имитация switch\n", "def first():\n", " print ('one')\n", "def second():\n", " print ('two') \n", "def third():\n", " print ('three')\n", "\n", "x = 2\n", "\n", "# плохой способ\n", "if (x == 1):\n", " first()\n", "elif (x == 2):\n", " second()\n", "elif (x == 3):\n", " third()\n", "\n", "# Python-style способ\n", "dct = {1: first, 2: second, 3: third}\n", "dct[x]()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "OrderedDict([('a', 1), ('b', 2), ('c', 3)])\n", "(Counter({'a': 3, 'b': 2, 'c': 1}), [('a', 3), ('b', 2)])\n", "(Counter({'a': 5, 'c': 2, 'b': 2}), Counter({'b': 2, 'a': 1}), Counter({'a': 2, 'c': 1}), Counter({'a': 3, 'b': 2, 'c': 1}))\n" ] } ], "source": [ "from collections import OrderedDict\n", "# словарь, в котором ключи упорядочены по времени добавления\n", "\n", "d = OrderedDict([(\"a\", 1), (\"b\", 2)])\n", "d[\"c\"] = 3\n", "print (d)\n", "\n", "# словарь-счётчик\n", "from collections import Counter\n", "c = Counter([\"a\", \"a\", \"b\", \"b\", \"c\"])\n", "c[\"a\"] += 1\n", "print (c, c.most_common(2))\n", "# можно работать со счётчиками как с мультимножествами\n", "c2 = Counter([\"a\", \"a\", \"c\"])\n", "print (c + c2, c - c2, c & c2, c | c2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## set (множества)\n", "\n", "только хэшируемые объекты могут быть элементами множества (числа, строки)\n", "\n", "есть ещё frozenset - неизменяемое множество" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'key2', 'key1'}\n", "True\n", "{1, 2, 'key2', 'key1'}\n", "{2, 'key2', 'key1'}\n", "{1, 2, 'key2', 'key1', 121}\n", "{1, 2, 'key2', 'key1', 121, 122, 123}\n", "{1, 2, 'key2', 121, 122, 123}\n" ] } ], "source": [ "s = {'key1', 'key1', 'key2'}\n", "print (s)\n", "print ('key2' in s)\n", "s = s.union({1,2})\n", "print (s)\n", "print (s.difference({1, 3, 4}))\n", "s.add(121) # добавить 1 элемент\n", "print (s)\n", "s.update([122, 123, 121]) # добавляем несколько элементов\n", "print (s) \n", "s.remove('key1') # если нет - исключение, есть ещё discard (без исключений)\n", "print (s)" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{1, 2}" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# преобразование типов\n", "x = [1, 2, 2]\n", "set(x)\n" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{2, 3}\n", "{2, 3}\n", "{1, 2, 3, 4}\n", "{1, 2, 3, 4}\n", "{1}\n", "{1}\n", "False\n", "False\n", "False\n" ] } ], "source": [ "a = {1, 2, 3}\n", "b = {2, 3, 4}\n", "\n", "# пересечение\n", "print (a & b)\n", "print (a.intersection(b)) # 2-й способ\n", "\n", "# объединение\n", "print (a | b)\n", "print (a.union(b)) # 2-й способ\n", "\n", "# разность\n", "print (a - b)\n", "print (a.difference(b)) # 2-й способ\n", "\n", "# вложения\n", "print (a <= b)\n", "print (a < b)\n", "print (a > b) \n", "\n" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{1, 2, 3, 4}\n", "{2}\n" ] } ], "source": [ "x, y, z = {1, 2}, {3}, {1, 3, 4}\n", "print (set.union(x, y, z))\n", "print (set.difference(x, y, z)) # x - y - z" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## file (файлы)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "f1 = open(\"file1.txt\", \"r\")\n", "f2 = open(\"file2.txt\", \"w\", encoding=\"cp1251\")\n", "for line in f1.readlines():\n", " f2.write(line)\n", "f2.close()\n", "f1.close()" ] }, { "cell_type": "code", "execution_count": 160, "metadata": { "collapsed": true }, "outputs": [], "source": [ "f = open(\"file.txt\", \"r\", 1)\n", "for line in f:\n", " # ...\n", "f.close()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# чтобы не забывать закрывать файлы\n", "with open('tmp.txt') as fin:\n", " for line in fin:\n", " # ...\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# файлоподобные объекты\n", "import urllib\n", "f1 = urllib.urlopen(\"http://python.onego.ru\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## модули\n", "\n", "**модуль** - один файл с расширением *.py (сейчас уже и zip-архив)\n", "\n", "задаёт своё пространство имён\n", "\n", "**пакет** - директория, в которой есть файл __init__.py (просто для организации кода)\n", "\n", "Может содержать поддериктории. Пользователю не так важно, с чем работать\n", "\n", "pak1\n", "|-- __init__.py\n", "|--pak12\n", "| |-- __init__.py\n", "| |-- f.py\n", "|--h.py\n", "\n", "from pak1.pak12 import f" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2004-11-20\n", "datetime\n", "Fast implementation of the datetime type.\n", "C:\\Anaconda3\\lib\\datetime.py\n", "2004-11-20\n", "2004-11-20\n" ] } ], "source": [ "import datetime # импортируем модуль\n", "d = datetime.date(2004, 11, 20) # появляется объект с соответствующим названием\n", "print (d)\n", "\n", "print (datetime.__name__) # имя\n", "print (datetime.__doc__) # описание\n", "print (datetime.__file__) # файл\n", "\n", "import datetime as dt # сокращение имени модуля\n", "print (dt.date(2004, 11, 20))\n", "\n", "from datetime import date as dt # импортирование конкретной функции\n", "print (dt(2004, 11, 20))\n", "\n", "# from datetime import * # лучше не использовать" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3\\\\python35.zip',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3\\\\DLLs',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3\\\\lib',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3',\n", " 'c:\\\\users\\\\александр дьяконов\\\\anaconda3\\\\lib\\\\site-packages\\\\setuptools-20.7.0-py3.5.egg',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3\\\\lib\\\\site-packages',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3\\\\lib\\\\site-packages\\\\Sphinx-1.3.1-py3.5.egg',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3\\\\lib\\\\site-packages\\\\cryptography-1.0.2-py3.5-win-amd64.egg',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3\\\\lib\\\\site-packages\\\\win32',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3\\\\lib\\\\site-packages\\\\win32\\\\lib',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3\\\\lib\\\\site-packages\\\\Pythonwin',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\Anaconda3\\\\lib\\\\site-packages\\\\IPython\\\\extensions',\n", " 'C:\\\\Users\\\\Александр Дьяконов\\\\.ipython']" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import sys\n", "# здесь питон ищет модули\n", "sys.path\n", "\n", "# или\n", "from sys import path\n", "path" ] }, { "cell_type": "code", "execution_count": 168, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "win32\n", "3.5.1 |Anaconda 2.4.0 (64-bit)| (default, Feb 16 2016, 09:49:46) [MSC v.1900 64 bit (AMD64)]\n" ] } ], "source": [ "print (sys.platform)\n", "\n", "print (sys.version)" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "...\n" ] } ], "source": [ "# если модуль пытаются выполнить, то у переменной __name__ специальное значение\n", "if __name__ ==\"__main__\":\n", " print (\"...\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# при повторном импорте нет перезагруки модуля\n", "# (это, в том числе, борьба с циклическими импортами)\n", "\n", "reload(module) # перезегрузка модуля\n", "# в 3м питоне по-другому! - importlib.reload" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "# import pre as re\n", "# digits = re.compile(\"\\d+\")\n", "# digits" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## enumerate" ] }, { "cell_type": "code", "execution_count": 142, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 A 65\n", "1 B 66\n", "2 C 67\n" ] } ], "source": [ "#--\n", "for i, c in enumerate(\"ABC\"):\n", " print (i, c, ord(c))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'c': 3, 'b': 2, 'a': 1}\n", "{'c': 3, 'b': 2, 'a': 1}\n" ] } ], "source": [ "#--\n", "def myf(a=1, b=2):\n", " c = 3\n", " print (vars()) # локальные имена\n", " print (locals()) # локальные имена\n", " d = 1\n", " # print (globals()) # глобальные имена\n", " \n", "myf()" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#--\n", "a = 1\n", "b = 2\n", "c = eval('a + b') # вычисление выражений\n", "# eval('c = a + b') # нельзя так\n", "c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ООП" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] }, { "data": { "text/plain": [ "'привет'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class A:\n", " pass\n", "\n", "a = A()\n", "a.attr = 1 # setattr(a, 'attr', 1)\n", "\n", "try:\n", " # if hasattr(a, 'attr'):\n", " print (a.attr) # getattr(a, 'attr')\n", "except:\n", " print (None)\n", "del a.attr # delattr(a, 'attr')\n", "\n", "# классы обычные объекты - их можно модифицировать\n", "A.method = lambda x: \"привет\"\n", "a.method()" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['one']\n", "text: two\n" ] } ], "source": [ "# как ещё можно задавать класс\n", "# можно использовать для генерации во время выполнения программы\n", "def pr(self, txt):\n", " print('text:', txt)\n", "\n", "MyList = type('MyList', (list,), dict(a=1,pr=pr))\n", "\n", "ml = MyList()\n", "ml.append('one')\n", "print (ml)\n", "ml.pr('two')" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "type" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "MyList.__class__.__class__" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## копирование объектов" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2000 1000\n", "74240048 63401840\n" ] } ], "source": [ "# УБРАТЬ???\n", "# все имена - ссылки\n", "a = 1000\n", "b = a\n", "a = 2000\n", "print (a, b)\n", "print (id(a), id(b))" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 [1, 10, 3]\n", "20 [1, 10, 3]\n" ] } ], "source": [ "# УБРАТЬ???\n", "# но не во всех случаях об этом надо заботиться\n", "s = [1, 2, 3]\n", "a = s[1]\n", "s[1] = 10\n", "print (a, s)\n", "\n", "a = 20\n", "print(a, s)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[1], [0]]" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from copy import copy\n", "x = [copy([0]) for i in range(2)]\n", "x[0][0] = 1\n", "x" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# все имена - ссылки на объекты\n", "a = [1, 2]\n", "b = [a] * 3 # состоит из идентичных (!) объектов\n", "print (b)\n", "b[0][0] = 0\n", "print (b)\n", "print (id(b[0]), id(b[1]), id(b[2]))" ] }, { "cell_type": "code", "execution_count": 182, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1, 2], [1, 2], [1, 2]]\n", "[[0, 2], [1, 2], [1, 2]]\n", "74362568 74359240 74359880\n" ] } ], "source": [ "from copy import copy\n", "a = [1, 2]\n", "b = [copy(a) for i in range(3)] # состоит из разных объектов\n", "print (b)\n", "b[0][0] = 0\n", "print (b)\n", "print (id(b[0]), id(b[1]), id(b[2]))" ] }, { "cell_type": "code", "execution_count": 184, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[0, 1], [0, 1]]\n", "[[0, 1], [0, 1]]\n" ] } ], "source": [ "# copy - не помогает...\n", "a = 1\n", "b = [a, a]\n", "c = [b, b]\n", "c2 = copy(c)\n", "c2[0][0] = 0\n", "print (c)\n", "print (c2)" ] }, { "cell_type": "code", "execution_count": 185, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1, 1], [1, 1]]\n", "[[0, 1], [0, 1]]\n" ] } ], "source": [ "from copy import deepcopy\n", "# deepcopy - не помогает... (частично ;)\n", "a = 1\n", "b = [a, a]\n", "c = [b, b]\n", "c2 = deepcopy(c)\n", "c2[0][0] = 0\n", "print (c)\n", "print (c2)" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(72882632, 72882632)" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = [[0]]*2\n", "id(x[0]), id(x[1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Функциональное программирование\n", "\n", "* Есть функции первого класса / высшего порядка\n", "(принимают другие функции в качестве аргументов или возвращают другие функции, их можно присваивать и хранить)\n", "* Рекурсия – основная управляющая структура в программе\n", "(нет цикла – он реализован через рекурсию)\n", "•\tОбработка списков (например, print(len([1+1, 1/0])))\n", "* Запрещение побочных эффектов у функций\n", "(чистые функции – зависят только от своих параметров и возвращают только свой результат)\n", "* Описываем не шаги к цели, а математическую зависимость данные–цель\n", "(в идеале, программа - одно выражение с сопутствующими определениями)" ] }, { "cell_type": "code", "execution_count": 192, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "14\n" ] } ], "source": [ "from operator import add, mul\n", "\n", "print (add(2, mul(3, 4))) # операции это тоже функции" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "21\n", "31\n" ] } ], "source": [ "# определение функции\n", "def inc(n, delta=1): # необязательный аргумент со значением по умолчанию\n", " return n+delta\n", "\n", "myadd = inc # эта же функция (просто другте имя)\n", "\n", "print (inc(20))\n", "print (myadd(30))" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(None, None)\n", "\n", " помощь\n", " \n", "Help on function g in module __main__:\n", "\n", "g()\n", " помощь\n", "\n" ] } ], "source": [ "# если функция ничего не возвращает, то она возвращает None\n", "\n", "def f():\n", " pass\n", "\n", "\n", "def g():\n", " \"\"\"\n", " помощь\n", " \"\"\"\n", " def h():\n", " # можно объявлять функцию внутри функции\n", " print ('h')\n", " 10\n", " \n", "print (f(), g())\n", "\n", "print g.__doc__\n", "\n", "help(g)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x=3, y=4\n", "x=3, y=2\n", "x=20, y=10\n", "x=1, y=0\n" ] } ], "source": [ "# именованные аргументы\n", "def f(x=1, y=2):\n", " print ('x=%g, y=%g' % (x, y))\n", " \n", "f(3, 4)\n", "f(3)\n", "f(y=10, x=20)\n", "f(y=0)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['my', 'long', 'text', '...']\n" ] } ], "source": [ "# ???\n", "def wrap(text, width=70, **kwargs):\n", " from textwrap import TextWrapper\n", " # kwargs - словарь с именами и значениями аргументов\n", " w = TextWrapper(width=width, **kwargs)\n", " return w.wrap(text)\n", "\n", "print (wrap(\"my long text ...\", width=4))\n", "# wrap('abc', 70, 'def', 2)" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(5, 1)\n", "(4, 0)\n", "(7, 1)\n", "(6, 2)\n" ] } ], "source": [ "# сколько угодно аргументов - \"упаковка аргументов\"\n", "def max_min(*args):\n", " # args - список аргументов в порядке их указания при вызове\n", " return max(args), min(args)\n", "\n", "print (max_min(1, 2, 3, 4, 5))\n", "print (max_min(*[4, 0, 3]))\n", "print (max_min(*(1, 7, 3)))\n", "print (max_min(*{6, 2, 4}))\n", "\n", "# возвратить можно только одно значение, но оно м.б. кортежом" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'c': 1, 'a': 3, 'b': 7}\n", "{'c': 1, 'a': 3, 'b': 7}\n" ] } ], "source": [ "# \"бесполезная упаковка\"\n", "def f(**x):\n", " print (x)\n", "\n", "f(**{'a': 3, 'b': 7, 'c': 1})\n", "\n", "\n", "def g(x):\n", " print (x)\n", "\n", "g({'a': 3, 'b': 7, 'c': 1})" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 [1, 2]\n", "for\n", "0 [1, 2]\n", "0 [1]\n" ] }, { "data": { "text/plain": [ "[0, 1, 2, 3, 4, 6]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# ещё про распаковку\n", "# этот код работает лишь в Python3!!!\n", "first, *other = range(3)\n", "print (first, other)\n", "\n", "print ('for')\n", "for a, *b in [range(3), range(2)]:\n", " print (a,b)\n", " \n", "[*range(5), 6]" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 3, 'b': 2}" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# распаковка при инициализации контейнера\n", "# в Python3\n", "d = {'a':1, 'b':2}\n", "d = {**d, 'a':3}\n", "d" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "аргументы:\n", "1\n", "(2, [3, 4])\n", "{'b': -1, 'a': 0}\n", "подробнее о **kwargs:\n", "b = -1\n", "a = 0\n", "аргументы:\n", "1\n", "()\n", "{}\n", "подробнее о **kwargs:\n" ] } ], "source": [ "# аргументы функции\n", "# фиксированные (здесь - 1 обязательно)\n", "# произвольные\n", "# любые\n", "def swiss_knife(arg1, *args, **kwargs):\n", " print ('аргументы:')\n", " print (arg1)\n", " print (args)\n", " print (kwargs)\n", " print ('подробнее о **kwargs:')\n", " for k, v in kwargs.items():\n", " print (k,'=',v)\n", " return None\n", "\n", "swiss_knife(1, 2, [3, 4], b=-1, a=0)\n", "# swiss_knife(1, 2, b=-1, a=0, [3, 4]) # так нельзя!\n", "swiss_knife(1)" ] }, { "cell_type": "code", "execution_count": 231, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "аргументы:\n", "{'b': 2, 'a': 1}\n", "()\n", "{}\n", "аргументы:\n", "b\n", "('a',)\n", "{}\n", "аргументы:\n", "[1, 2, 3]\n", "()\n", "{}\n", "аргументы:\n", "1\n", "(2, 3)\n", "{}\n" ] } ], "source": [ "# передача нескольких аргументов\n", "d = {'a':1, 'b':2}\n", "s = [1, 2, 3]\n", "swiss_knife(d)\n", "swiss_knife(*d)\n", "swiss_knife(s)\n", "swiss_knife(*s) # такая передача аргументов!" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# лямбда-функции (анонимные)\n", "func = lambda x, y: x + y\n", "\n", "print (func(1, 2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## функции первого класса\n", "\n", "могут быть\n", "* созданы во время выполнения\n", "* присвоены переменной\n", "* переданы функции в качестве аргументов\n", "* возвращены функцией в качестве результата" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "13\n", "10\n" ] } ], "source": [ "# функции первого класса\n", "def create_adder(x):\n", " def adder(y): # определяем функцию внутри\n", " return x + y\n", " return adder # её же возвращаем\n", "\n", "add_10 = create_adder(10)\n", "print (add_10(3))\n", "f = add_10 # та же функция\n", "del add_10 # не удаляет саму функцию\n", "print(f(0))\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'adder'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# интересное наблюдение\n", "f.__name__" ] }, { "cell_type": "code", "execution_count": 212, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1]\n", "[1, 2]\n", "[1, 2, 3]\n" ] } ], "source": [ "# lst - хранится...\n", "def mylist(val, lst=[]):\n", " lst.append(val)\n", " return lst\n", "\n", "print (mylist(1))\n", "print (mylist(2))\n", "print (mylist(3))" ] }, { "cell_type": "code", "execution_count": 216, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1]\n", "[2]\n", "[3]\n" ] } ], "source": [ "# lst не сохраняется!... часто очень полезно\n", "def mylist(val, lst=None):\n", " lst = lst or []\n", " lst.append(val)\n", " return lst\n", "\n", "print (mylist(1))\n", "print (mylist(2))\n", "print (mylist(3))" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "# apply, reduce - не поддерживается больше" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "24\n", "(((1*2)*3)*4)\n" ] } ], "source": [ "from functools import reduce\n", "\n", "print (reduce(lambda x, y: x * y, [1, 2, 3, 4])) # ((1*2)*3)*4\n", "\n", "print (reduce(lambda x, y: '(' + str(x) + '*' + str(y) + ')', [1, 2, 3, 4]))\n", "\n", "# print (reduce(merge, [[1,2], range(2), 'abc'])) # Python 3?" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "range(0, 3)\n", "[0, 1, 2]\n", "0\n", "1\n", "2\n" ] } ], "source": [ "print (range(3)) # в 3м питоне - не список\n", "print (list(range(3)))\n", "for i in range(3):\n", " print (i)" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 1, 4, 6]\n", "[1, 2, 3, 4]\n" ] } ], "source": [ "# map\n", "l1 = [1, 2, 3, 4]\n", "l2 = [0, -1, +1, +2] # если разной длины - то по длине наименьшей\n", "\n", "print (list(map(lambda x, y: x + y, l1, l2)))\n", "\n", "print (list(map(max, l1, l2)))" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 9]\n", "[0, 1, 4]\n" ] } ], "source": [ "# map\n", "l = [1, 2, 3]\n", "print (list(map(lambda x: x * x, l)))\n", "print (list(map(lambda x: x * x, range(3))))" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['П', 'р', 'и', 'в', 'е', 'т', 'м', 'и', 'р']\n" ] }, { "data": { "text/plain": [ "[1, 3, 5, 7, 9]" ] }, "execution_count": 101, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# filter\n", "\n", "print (list(filter(lambda x: x.isalpha(), 'Привет, мир!'))) ### перезапустить;)\n", "\n", "list(filter(lambda x: x % 2, range(10)))" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[12, 1, 2]" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# так надо было делать в Python 2.x - from types import IntType - ТАК ТОЖЕ РАБОТАЕТ\n", "lst = [12, 1.2, '12', 1, 2]\n", "list(filter(lambda x: type(x) is int, lst))" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 'a', 0), (1, 'b', 1), (2, 'c', 0), (3, 'd', 1), (4, 'e', 0)]" ] }, "execution_count": 103, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# zip\n", "# - сюда пример\n", "x = range(5)\n", "y = 'abcde'\n", "z = [0,1,0,1,0]\n", "\n", "list(zip(x,y,z)) # list - python3" ] }, { "cell_type": "code", "execution_count": 104, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[('П', 'р'), ('р', 'и'), ('и', 'в'), ('в', 'е'), ('е', 'т'), ('т', '!')]" ] }, "execution_count": 104, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# сформировать перечень пар соседних букв\n", "x = 'Привет!'\n", "\n", "# можно подавать разные по длине аргументы\n", "list(zip(x, x[1:]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Переменные и видимость" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "# глобальные переменные\n", "\n", "globvar = 0\n", "\n", "def set_globvar_to_one():\n", " global globvar # глобальная - без этого нельзя сделать, например, globvar+=1\n", " globvar = 1 # если не объявить глобальной - тут будет локальная\n", "\n", "def print_globvar():\n", " print (globvar) # не надо объявлять\n", "\n", "set_globvar_to_one()\n", "print_globvar() " ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "ename": "SyntaxError", "evalue": "no binding for nonlocal 'a' found (, line 5)", "output_type": "error", "traceback": [ "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m5\u001b[0m\n\u001b[0;31m nonlocal a\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m no binding for nonlocal 'a' found\n" ] } ], "source": [ "# области видимости\n", "# nonlocal ??? - для охвата \"объемлющей области\"\n", "a = 0\n", "def f():\n", " nonlocal a\n", " #global a\n", " a+=1\n", " return (a)\n", "\n", "print (f(), a)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "locals = {'min': 2}\n", "locals = {'max': 10, 'g': , 'min': 1}\n", "locals = {'min': 2}\n" ] }, { "data": { "text/plain": [ "(, 0)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def f():\n", " min = 1 # локальная переменная\n", " max = 10\n", " def g():\n", " min = 2 # другая локальная переменная\n", " # print (min, max) # max берём из f() - уберите комментарий;)\n", " print ('locals = ' + str(locals()))\n", " g()\n", " # print (min)\n", " print ('locals = ' + str(locals()))\n", " g()\n", "\n", "max = 0 # глобальная переменная\n", "f()\n", "min, max # встроенная функция" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### списковые включения (List Comprehensions)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(1, 0), (2, 0), (2, 1)]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# списковые включения\n", "\n", "[(i, j) for i in range(3) for j in range (5) if i > j]" ] }, { "cell_type": "code", "execution_count": 250, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 4, 9, 16]" ] }, "execution_count": 250, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[x**2 for x in range(5)]" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e')]\n", "{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}\n", "['a=0', 'b=1', 'c=2', 'd=3', 'e=4']\n" ] } ], "source": [ "# zip\n", "\n", "print (list(zip(range(5), 'abcde')))\n", "\n", "print (dict(zip(range(5), 'abcde')))\n", "\n", "print (['%s=%s' % (x,y) for y, x in zip(range(5), 'abcde')])" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{10, 20, 100}" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Set Comprehensions\n", "lst = [10, 5, 100, 3, 20, 10, 3, 20]\n", "{x for x in lst if 10*round(x / 10) == x}" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 0, 'b': 1, 'c': 2}" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Dictionary Comprehensions\n", "\n", "{x:y for y, x in zip(range(5), 'abcde') if y<3}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Итераторы\n", "\n", "**for** работает с любой последовательностью (есть __next__ до исключения StopIteration)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "[3, 4, 5]\n" ] } ], "source": [ "# что такое итератор\n", "it = iter([1, 2, 3, 4, 5])\n", "\n", "print (next(it))\n", "print (next(it))\n", "print ([x for x in it])\n", "# print (next(it)) # исключение" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[' ', ' ', ' ']\n" ] } ], "source": [ "# КАК ЕСТЬ\n", "def forit(mystate=[]):\n", " if len(mystate) < 3:\n", " mystate.append(\" \")\n", " return \" \"\n", "\n", "it2 = iter(forit, None) # если не возвращает значения явно, то None\n", "\n", "print ([x for x in it2])" ] }, { "cell_type": "code", "execution_count": 275, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]\n", "0 a\n", "1 b\n", "2 c\n", "3 d\n" ] } ], "source": [ "print (list(x for x in enumerate(\"abcd\")))\n", "\n", "for i, j in enumerate(\"abcd\"):\n", " print (i, j)" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0: 'test', 1: 'train', 2: 'val'}" ] }, "execution_count": 109, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dict(enumerate(['test', 'train', 'val']))" ] }, { "cell_type": "code", "execution_count": 277, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n", "a\n", "b\n", "m\n", "m\n" ] } ], "source": [ "for i in sorted('mamba'): # правда, это список\n", " print (i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Модуль itertools" ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3, 4, 5]\n", "[1, 1, 1, 1]\n", "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]\n", "[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]\n", "e[3:6] [3, 4, 5]\n", "e[3:9:2] [3, 5, 7]\n", "[5, 6, 7, 8, 9]\n", "[0, 1, 2] [0, 1, 2] []\n", "[('A', 'A'), ('A', 'B'), ('B', 'A'), ('B', 'B')]\n", "[('Y', 'N'), ('N', 'Y')]\n", "[('A', 'B'), ('A', 'C'), ('B', 'C')]\n", "[('A', 'A'), ('A', 'B'), ('B', 'B')]\n" ] } ], "source": [ "# модуль itertools\n", "\n", "from itertools import chain\n", "\n", "it1 = iter([1, 2, 3])\n", "it2 = iter([4, 5])\n", "\n", "a = []\n", "for i in chain(it1, it2): # соединение 2х итераторов\n", " a.append(i)\n", "print (a)\n", "\n", "from itertools import repeat\n", "\n", "b = []\n", "for i in repeat(1, 4): # повторение итератора\n", " b.append(i)\n", "print (b)\n", "\n", "from itertools import count\n", "c = []\n", "for i in count(1): # бесконечный итератор\n", " c.append(i)\n", " if i > 10:\n", " break\n", "print(c)\n", "\n", "from itertools import cycle\n", "d = []\n", "for i, j in enumerate(cycle([1,2,3])):\n", " d.append(j)\n", " if i>10:\n", " break\n", "print (d)\n", "\n", "from itertools import islice\n", "e1 = islice(range(10), 3, 6) # срезы\n", "e2 = islice(range(10), 3, 9, 2)\n", "print (\"e[3:6] \" + str(list(e1))) \n", "print (\"e[3:9:2] \" + str(list(e2))) \n", "\n", "from itertools import dropwhile # ещё есть takewhile\n", "f = dropwhile(lambda x: x < 5, range(10))\n", "print (list(f))\n", "\n", "from itertools import tee\n", "it = range(3)\n", "a, b, c = tee(it, 3) # три независимые копии итераторов\n", "tmp = list(c) # этот итератор \"уничтожится\"\n", "print (list(a), list(b), list(c))\n", "\n", "\n", "from itertools import product\n", "it = product(\"AB\", repeat=2) # декартово произведение\n", "print (list(it))\n", "\n", "from itertools import permutations\n", "it = permutations(\"YN\") # перестановки\n", "print (list(it))\n", "\n", "from itertools import combinations\n", "it = combinations(\"ABC\", 2) # сочетания (без повторений)\n", "print (list(it))\n", "\n", "from itertools import combinations_with_replacement\n", "it = combinations_with_replacement(\"AB\", 2) # сочетания c повторениями\n", "print (list(it))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A 1\n", "B 2\n", "A 3\n", "C 1\n", "B 1\n", "C 2\n" ] } ], "source": [ "from itertools import groupby\n", "it = groupby(\"ABBAAACBCC\") # группировка\n", "for i, j in it:\n", " print (i, sum(1 for _ in j)) # list(j)" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "ename": "ImportError", "evalue": "cannot import name 'imap'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# не поддерживается!!!\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mitertools\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mimap\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;31m# izip\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mImportError\u001b[0m: cannot import name 'imap'" ] } ], "source": [ "# не поддерживается!!!\n", "from itertools import imap\n", "# izip\n" ] }, { "cell_type": "code", "execution_count": 294, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "takewhile 1\n", "dropwhile -2\n", "dropwhile 3\n", "dropwhile -3\n" ] } ], "source": [ "from itertools import takewhile\n", "for i in takewhile(lambda x: x > 0, [1, -2, 3, -3]): # выдаёт пока истино\n", " print ('takewhile', i)\n", " \n", "from itertools import dropwhile\n", "for i in dropwhile(lambda x: x > 0, [1, -2, 3, -3]): # не выдаёт пока истино, но потом - всё\n", " print ('dropwhile', i)" ] }, { "cell_type": "code", "execution_count": 301, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'map' object is not callable", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mlst\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mmath\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m*\u001b[0m\u001b[1;36m.4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m30\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mk\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mitertools\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgroupby\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlst\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mx\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mprint\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mk\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlst\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mTypeError\u001b[0m: 'map' object is not callable" ] } ], "source": [ "# НЕ РАБОТАЕТ\n", "import itertools, math\n", "lst = map(lambda x: math.sin(x*.4), range(30))\n", "for k, i in itertools.groupby(lst, lambda x: x > 0):\n", " print (k, lst(i))" ] }, { "cell_type": "code", "execution_count": 306, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(, )" ] }, "execution_count": 306, "metadata": {}, "output_type": "execute_result" } ], "source": [ "itertools.tee(range(3), 2) # клонирование итераторов" ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from itertools import combinations\n", "\n", "it = combinations(range(3), 2)\n", "len(list(it))" ] }, { "cell_type": "code", "execution_count": 118, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]" ] }, "execution_count": 118, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# свой итератор\n", "\n", "class Fibonacci:\n", " \"\"\"Итератор последовательности Фибоначчи до N\"\"\"\n", " \n", " def __init__(self, N):\n", " self.n, self.a, self.b, self.max = 0, 0, 1, N\n", " \n", " def __iter__(self):\n", " return self\n", " \n", " def __next__(self): # должна быть такая функция ( # Python 2: def next(self))\n", " if self.n < self.max:\n", " a, self.n, self.a, self.b = self.a, self.n+1, self.b, self.a+self.b\n", " return a\n", " else:\n", " raise StopIteration\n", " \n", "# for i in Fibonacci(10):\n", "# print (i)\n", "list(Fibonacci(10))" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2, 3, 4, 5]" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# упрощённый итератор\n", "class Identity:\n", " def __getitem__(self, idx):\n", " if idx > 5:\n", " raise IndexError(idx)\n", " return idx\n", "\n", "list(Identity())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Простые генераторы\n", "\n", "-- помогают делать ленивые вычисления (lazy computations)\n", "\n", "не вычисляет все значения сразу - делает это поитерациям\n", "\n", "**yield** - похожа на return, но работа функции приостанавливается и выдаётся значение" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "1\n", "2\n", "3\n", "5\n", "8\n", "13\n", "21\n", "34\n" ] } ], "source": [ "def Fib(N):\n", " a, b = 0, 1\n", " for i in range(N):\n", " yield a # вместо return для выдачи следующего значения\n", " a, b = b, a + b\n", "\n", "for i in Fib(10):\n", " print (i)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 2, 4, 6, 8]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def double_numbers(iterable):\n", " for i in iterable:\n", " yield i + i\n", " \n", "list(double_numbers(range(5)))" ] }, { "cell_type": "code", "execution_count": 119, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 1, 4, 9, 16]\n", " at 0x7efe441ce678>\n", "30\n" ] } ], "source": [ "# генераторное выражение\n", "print ( [x * x for x in range(5)] ) # это список\n", "print ( (x * x for x in range(5)) ) # а это - генераторное выражение\n", "# не порождается коллекция;)\n", "print ( sum(x * x for x in range(5)) ) # тут без скобок - тоже генераторое выражение" ] }, { "cell_type": "code", "execution_count": 120, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "использование генераторного выражения:\n", "0\n", "1\n", "4\n", "9\n", "16\n", "переиспользование:\n" ] } ], "source": [ "gen = (x*x for x in range(5))\n", "\n", "print ('использование генераторного выражения:')\n", "for y in gen:\n", " print (y)\n", " \n", "print ('переиспользование:') # ничего не будет!\n", "for y in gen:\n", " print (y)" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ищем 'Мир'\n", "нашли в: Предложение с Миром\n", "нашли в: Миру мир!\n" ] } ], "source": [ "# сопрограммы (coroutines)\n", "\n", "# больше одной точки входа\n", "# остановка исполнения, сохранение состояния и продолжение\n", "\n", "def grep(pattern):\n", " print(\"Ищем {!r}\".format(pattern))\n", " while True:\n", " line = yield # точка входа в line засылает метод send\n", " if pattern in line:\n", " print('нашли в: ' + line)\n", "\n", "gen = grep(\"Мир\")\n", "\n", "next(gen) # обязательно нужно - это инициализация (инициализацию можно спрятать в декораторе)\n", "gen.send(\"Предложение\")\n", "gen.send(\"Предложение с Миром\")\n", "gen.send(\"Предложение с миром\")\n", "gen.send(\"Миру мир!\")" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4, 5, 6]" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def f():\n", " yield 1\n", " yield 2\n", " yield 3\n", " # return 10 - нет эффекта\n", "\n", "def g():\n", " x = yield from f() # взять выход у f!\n", " yield 4\n", " yield 5\n", " yield 6\n", " # return 100 - нет эффекта\n", " \n", "list(g())" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Декораторы\n", "для модификации функции, сохраняя читабельность кода" ] }, { "cell_type": "code", "execution_count": 125, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "20" ] }, "execution_count": 125, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# пример цепочки декораторов\n", "\n", "def square(f): # на вход - функция\n", " return lambda x: f(x * x) # выход - функция, которая будет реально выполняться\n", "\n", "def add1(f): # на вход - функция\n", " return lambda x: f(x + 1) # выход - функция, которая будет реально выполняться\n", "\n", "# два декоратора у функции\n", "@square\n", "@add1\n", "def time2(x):\n", " return (x * 2)\n", "\n", "time2(3) # (3*3 + 1)*2" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "внутри my_decorator.__init__()\n", "внутри aFunction()\n", "окончание декорирования aFunction()\n", "внутри my_decorator.__call__()\n" ] } ], "source": [ "class my_decorator(object):\n", " def __init__(self, f):\n", " print(\"внутри my_decorator.__init__()\")\n", " f() # это просто создание функции f\n", " def __call__(self):\n", " print(\"внутри my_decorator.__call__()\")\n", " \n", "@my_decorator\n", "def aFunction():\n", " print(\"внутри aFunction()\")\n", " \n", "print(\"окончание декорирования aFunction()\")\n", "\n", "aFunction() # вызов функции\n", "# на самом деле вызывается my_decorator.__call__()" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Вызовы функций:\n", "вызов - func1\n", "работа func1()\n", "выход - func1\n", "вызов - func2\n", "работа func2()\n", "выход - func2\n" ] } ], "source": [ "# зачем нужны декораторы:\n", "\n", "class entry_exit(object):\n", " def __init__(self, f):\n", " self.f = f\n", " def __call__(self):\n", " print(\"вызов - \", self.f.__name__)\n", " self.f()\n", " print(\"выход - \", self.f.__name__)\n", " \n", "@entry_exit\n", "def func1():\n", " print(\"работа func1()\")\n", " \n", "@entry_exit\n", "def func2():\n", " print(\"работа func2()\")\n", "\n", "print ('Вызовы функций:')\n", "func1()\n", "func2()" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Вызовы\n", "Вызов: func1\n", "работа func1()\n", "Выход: func1\n", "Вызов: func2\n", "работа func2()\n", "Выход: func2\n", "func1\n" ] } ], "source": [ "# здесь декоратор - функция\n", "# главное, чтобы декоратор можно было вызвать\n", "def entry_exit(f):\n", " def new_f():\n", " print(\"Вызов: \", f.__name__)\n", " f()\n", " print(\"Выход: \", f.__name__)\n", " new_f.__name__ = f.__name__ # меняем даже имя функции (попробуйте убрать)\n", " return new_f\n", "\n", "@entry_exit\n", "def func1():\n", " print(\"работа func1()\")\n", " \n", "@entry_exit\n", "def func2():\n", " print(\"работа func2()\")\n", "\n", "print ('Вызовы')\n", "func1()\n", "func2()\n", "print(func1.__name__)" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Inside __init__()\n", "После декорации...\n", "Inside __call__()\n", "Аргументы: say hello argument list\n", "After self.f(*args)\n", "Ещё раз...\n", "Inside __call__()\n", "Аргументы: a different set of arguments\n", "After self.f(*args)\n" ] } ], "source": [ "# декоратор без аргументов\n", "class decorator_without_arguments(object):\n", " def __init__(self, f):\n", " \"\"\"\n", " Если пишем декоратор без аргументов,\n", " то передаём в конструкторе функцию\n", " \"\"\"\n", " print(\"Inside __init__()\")\n", " self.f = f\n", " def __call__(self, *args):\n", " \"\"\"\n", " В __call__ method передаём аргументы.\n", " \"\"\"\n", " print(\"Inside __call__()\")\n", " self.f(*args)\n", " print(\"After self.f(*args)\")\n", " \n", "@decorator_without_arguments\n", "def sayHello(a1, a2, a3, a4):\n", " print('Аргументы:', a1, a2, a3, a4)\n", " \n", "print(\"После декорации...\")\n", "sayHello(\"say\", \"hello\", \"argument\", \"list\")\n", "print(\"Ещё раз...\")\n", "sayHello(\"a\", \"different\", \"set of\", \"arguments\")\n" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "работа __init__()\n", "работа __call__()\n", "После декорации...\n", "работа wrapped_f()\n", "Аргументы: hello world 42\n", "Аргументы sayHello: say hello argument list\n", "выход из f(*args)\n", "Ещё раз...\n", "работа wrapped_f()\n", "Аргументы: hello world 42\n", "Аргументы sayHello: a different set of arguments\n", "выход из f(*args)\n" ] } ], "source": [ "# декоратор с аргументами\n", "\n", "class decorator_with_arguments(object):\n", " def __init__(self, arg1, arg2, arg3):\n", " \"\"\"\n", " Если пишем с аргументами, то их передаём в конструктор,\n", " а функция не передаётся!\n", " \"\"\"\n", " print(\"работа __init__()\")\n", " self.arg1 = arg1\n", " self.arg2 = arg2\n", " self.arg3 = arg3\n", " \n", " def __call__(self, f):\n", " \"\"\"\n", " Если пишем с аргументами, то __call__() вызывается лишь раз,\n", " как часть процесса декорации, ей можно передать только функцию!\n", " \"\"\"\n", " print(\"работа __call__()\")\n", " \n", " def wrapped_f(*args):\n", " print(\"работа wrapped_f()\")\n", " print(\"Аргументы:\", self.arg1, self.arg2, self.arg3)\n", " f(*args)\n", " print(\"выход из f(*args)\")\n", " \n", " return wrapped_f\n", " \n", "@decorator_with_arguments(\"hello\", \"world\", 42)\n", "def sayHello(a1, a2, a3, a4):\n", " print('Аргументы sayHello:', a1, a2, a3, a4)\n", " \n", "\n", "\n", "\n", "print(\"После декорации...\")\n", "sayHello(\"say\", \"hello\", \"argument\", \"list\")\n", "print(\"Ещё раз...\")\n", "sayHello(\"a\", \"different\", \"set of\", \"arguments\")" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Inside wrap()\n", "After decoration\n", "Preparing to call sayHello()\n", "Inside wrapped_f()\n", "Decorator arguments: hello world 42\n", "sayHello arguments: say hello argument list\n", "After f(*args)\n", "after first sayHello() call\n", "Inside wrapped_f()\n", "Decorator arguments: hello world 42\n", "sayHello arguments: a different set of arguments\n", "After f(*args)\n" ] } ], "source": [ "# декораторная функция с аргументами\n", "\n", "def decorator_function_with_arguments(arg1, arg2, arg3):\n", " def wrap(f):\n", " print(\"Inside wrap()\")\n", " def wrapped_f(*args):\n", " print(\"Inside wrapped_f()\")\n", " print(\"Decorator arguments:\", arg1, arg2, arg3)\n", " f(*args)\n", " print(\"After f(*args)\")\n", " return wrapped_f\n", " return wrap\n", "\n", "@decorator_function_with_arguments(\"hello\", \"world\", 42)\n", "def sayHello(a1, a2, a3, a4):\n", " print('sayHello arguments:', a1, a2, a3, a4)\n", " \n", "print(\"After decoration\")\n", "print(\"Preparing to call sayHello()\")\n", "sayHello(\"say\", \"hello\", \"argument\", \"list\")\n", "print(\"after first sayHello() call\")\n", "sayHello(\"a\", \"different\", \"set of\", \"arguments\")\n" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Обобщённые функции\n", "их реализация м.б. специализирована для конкретного типа" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "3\n", "[0, 1, 2, 3]\n" ] } ], "source": [ "print (len([1, 2, 3]))\n", "print (len({1, 2, 3}))\n", "print (len(range(4)))" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3]\n", "set([1, 2, 3])\n", "[0, 1, 2, 3]\n" ] } ], "source": [ "print (str([1, 2, 3]))\n", "print (str({1, 2, 3}))\n", "print (str(range(4)))" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6\n", "6\n", "6\n" ] } ], "source": [ "print (sum([1, 2, 3]))\n", "print (sum({1, 2, 3}))\n", "print (sum(range(4)))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas\n", "import imp\n", "\n", "imp.reload(pandas)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" } }, "nbformat": 4, "nbformat_minor": 1 }