{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "#### Кафедра дискретной математики МФТИ\n", "\n", "\n", "Никита Волков\n", "\n", "На основе http://www.inp.nsk.su/~grozin/python/\n", "\n", "# Кортежи\n", "\n", "Кортежи (tuples) очень похожи на списки, но являются неизменяемыми. Как мы видели, использование изменяемых объектов может приводить к неприятным сюрпризам.\n", "\n", "Кортежи пишутся в круглых скобках. Если элементов $>1$ или 0, это не вызывает проблем. Но как записать кортеж с одним элементом? Конструкция `(x)` абсолютно легальна в любом месте любого выражения, и означает просто `x`. Чтобы избежать неоднозначности, кортеж с одним элементом `x` записывается в виде `(x,)`." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(1, 2, 3)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "()" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1,)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(1,)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Скобки ставить не обязательно, если кортеж - единственная вещь в правой части присваивания." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = 1, 2, 3\n", "t" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Работать с кортежами можно так же, как со списками. Нельзя только изменять их." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(t)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t[1]" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3, 4, 5)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u = 4, 5\n", "t + u" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(4, 5, 4, 5)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 * u" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В левой части присваивания можно написать несколько переменных через запятую, а в правой кортеж. Это одновременное присваивание значений нескольким переменным." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x, y = 1, 2" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Сначала вычисляется кортеж в правой части, исходя из *старых* значений переменных (до этого присваивания). Потом одновременно всем переменным присваиваются новые значения из этого кортежа. Поэтому так можно обменять значения двух переменных." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x, y = y, x" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Это проще, чем в других языках, где приходится использовать третью переменную.\n", "\n", "# Множества\n", "\n", "В соответствии с математическими обозначениями, множества пишутся в фигурных скобках. Элемент может содержаться в множестве только один раз. Порядок элементов в множестве не имеет значения, поэтому питон их сортирует. Элементы множества могут быть любых типов." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0, 1, 5}" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = {0, 1, 0, 5, 5, 1, 0}\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Принадлежит ли элемент множеству?" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(True, False, False)" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 in s, 2 in s, 1 not in s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Множество можно получить из списка, или строки, или любого объекта, который можно использовать в `for` цикле (итерабельного)." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0, 1, 5}" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l = [0, 1, 0, 5, 5, 1, 0]\n", "set(l)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'а', 'б'}" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "set('абба')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Как записать пустое множество? Только так." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "set()" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "set()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Дело в том, что в фигурных скобках в питоне пишутся также словари (мы будем их обсуждать в следующем параграфе). Когда в них есть хоть один элемент, можно отличить словарь от множества. Но пустые фигурные скобки означают пустой словарь." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{}" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "{}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Работать с множествами можно как со списками." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(s)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "5\n" ] } ], "source": [ "for x in s:\n", " print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Это генератор множества (set comprehension)." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0, 1, 2, 3, 4}" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "{i for i in range(5)}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Объединение множеств." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0, 1, 2, 5}" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s2 = s | {2, 5}\n", "s2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Проверка того, является ли одно множество подмножеством другого." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(True, False, True, False)" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s < s2, s > s2, s <= s2, s >= s2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Пересечение." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{1, 2}" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s2 & {1, 2, 3}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Разность и симметричная разность." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0, 2}" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s2 - {1,3,5}" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0, 2, 3}" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s2 ^ {1,3,5}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Множества (как и списки) являются изменяемыми объектами. Добавление элемента в множество и исключение из него." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0, 1, 2, 4, 5}" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s2.add(4)\n", "s2" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0, 2, 4, 5}" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s2.remove(1)\n", "s2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Как и в случае `+=`, можно скомбинировать теоретико-множественную операцию с присваиванием." ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0, 1, 2, 4, 5}" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s2 |= {1, 2}\n", "s2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Приведенные выше операции можно записывать и в другом стиле" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{1, 2, 3, 4}\n", "{1, 2, 3, 4, 5}\n", "{2, 3, 4, 5}\n", "{2, 4}\n", "{3, 5}\n", "{2, 3, 4, 5, 6, 8}\n", "{3, 5, 6, 8}\n", "False\n", "True\n", "False\n", "True\n" ] } ], "source": [ "x = set([1, 4, 2, 4, 2, 1, 3, 4])\n", "print(x)\n", "\n", "x.add(5) # добавление элемента\n", "print(x)\n", "\n", "x.pop() # удаление элемента\n", "print(x)\n", "\n", "print(x.intersection(set([2, 4, 6, 8]))) # Пересечение\n", "print(x.difference(set([2, 4, 6, 8]))) # Разность\n", "print(x.union(set([2, 4, 6, 8]))) # Объединение\n", "print(x.symmetric_difference(set([2, 4, 6, 8]))) # Симметрическая разность\n", "\n", "print(x.issubset(set([2, 4, 6, 8]))) # Является ли подмножеством\n", "print(x.issubset(set(list(range(10)))))\n", "\n", "print(x.issuperset(set([2, 4, 6, 8]))) # Является ли надмножеством\n", "print(x.issuperset(set([2, 4])))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Существуют также неизменяемые множества. Этот тип данных называется `frozenset`. Операции над такими множествами подобны обычным, только невозможно изменять их (добавлять и исключать элементы).\n", "\n", "# Словари\n", "\n", "Словарь содержит пары ключ - значение (их порядок несущественен). Это один из наиболее полезных и часто используемых типов данных в питоне." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'one': 1, 'three': 3, 'two': 2}" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d = {'one': 1, 'two': 2, 'three': 3}\n", "d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Можно узнать значение, соответствующее некоторому ключу. Словари реализованы как хэш-таблицы, так что поиск даже в больших словарях очень эффективен. В языках низкого уровня (например, C) для построения хэш-таблиц требуется использовать внешние библиотеки и писать заметное количество кода. В скриптовых языках (perl, python, php) они уже встроены в язык, и использовать их очень легко." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['two']" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "ename": "KeyError", "evalue": "'four'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'four'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mKeyError\u001b[0m: 'four'" ] } ], "source": [ "d['four']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Можно проверить, есть ли в словаре данный ключ." ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(True, False)" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'one' in d, 'four' in d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Можно присваивать значения как имеющимся ключам, так и отсутствующим (они добавятся к словарю)." ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'one': -1, 'three': 3, 'two': 2}" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['one'] =- 1\n", "d" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'four': 4, 'one': -1, 'three': 3, 'two': 2}" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['four'] = 4\n", "d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Длина - число ключей в словаре." ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Можно удалить ключ из словаря." ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'four': 4, 'one': -1, 'three': 3}" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del d['two']\n", "d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Метод `get`, если он будет вызван с отсутствующим ключом, не приводит к ошибке, а возвращает специальный объект `None`. Он используется всегда, когда необходимо указать, что объект отсутствует (в какой-то мере он аналогичен `null` в C). Если передать методу `get` второй аргумент - значение по умолчанию, то будет возвращаться это значение, а не `None`." ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(-1, None)" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d.get('one'), d.get('five')" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(-1, 0)" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d.get('one', 0), d.get('five', 0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Словари обычно строят последовательно: начинают с пустого словаря, а затем добавляют ключи со значениями." ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{}" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d = {}\n", "d" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'zero': 0}" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['zero'] = 0\n", "d" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'one': 1, 'zero': 0}" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['one'] = 1\n", "d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "А это генератор словаря (dictionary comprehension)." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d = {i: i ** 2 for i in range(5)}\n", "d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ключами могут быть любые неизменяемые объекты, например, целые числа, строки, кортежи." ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{(0, 0): 1, (0, 1): 0, (1, 0): 0, (1, 1): -1}" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d = {}\n", "d[0, 0] = 1\n", "d[0, 1] = 0\n", "d[1, 0] = 0\n", "d[1, 1] = -1\n", "d" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d[0, 0] + d[1, 1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Словари, подобно спискам, можно использовать в `for` циклах. Перебираются имеющиеся в словаре ключи (в каком-то непредсказуемом порядке)." ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one 1\n", "two 2\n", "three 3\n" ] } ], "source": [ "d = {'one': 1, 'two': 2, 'three': 3}\n", "for x in d:\n", " print(x, ' ', d[x])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Метод `keys` возвращает список ключей, метод `values` - список соответствующих значений (в том же порядке), а метод `items` - список пар (ключ,значение). Точнее говоря, это не списки, а некоторые объекты, которые можно использовать в `for` циклах или превратить в списки функцией `list`. Если хочется написать цикл по упорядоченному списку ключей, то можно использовать `sorted(d.keys))`." ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(dict_keys(['one', 'two', 'three']),\n", " dict_values([1, 2, 3]),\n", " dict_items([('one', 1), ('two', 2), ('three', 3)]))" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d.keys(), d.values(), d.items()" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one 1\n", "three 3\n", "two 2\n" ] } ], "source": [ "for x in sorted(d.keys()):\n", " print(x, ' ', d[x])" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one 1\n", "two 2\n", "three 3\n" ] } ], "source": [ "for x, y in d.items():\n", " print(x, ' ', y)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [], "source": [ "del x, y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Что есть истина? И что есть ложь? Подойдём к этому философскому вопросу экспериментально." ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(False, True)" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool(False), bool(True)" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool(None)" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(False, True)" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool(0), bool(123)" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(False, True)" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool(''), bool(' ')" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(False, True)" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool([]), bool([0])" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(False, True)" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool(set()), bool({0})" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(False, True)" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool({}), bool({0: 0})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "На выражения, стоящие в булевых позициях (после `if`, `elif` и `while`), неявно напускается функция `bool`. Некоторые объекты интерпретируются как `False`: число 0, пустая строка, пустой список, пустое множество, пустой словарь, `None` и некоторые другие. Все остальные объекты интерпретируются как `True`. В операторах `if` или `while` очень часто используется список, словарь или что-нибудь подобное, что означает делай что-то если этот список (словарь и т.д.) не пуст.\n", "\n", "Заметим, что число с плавающей точкой 0.0 тоже интерпретируется как `False`. Это использовать категорически не рекомендуется: вычисления с плавающей точкой всегда приближённые, и неизвестно, получите Вы 0.0 или `1.234E-12`.\n", "Лучше напишите `if abs(x)" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "collapsed": true }, "outputs": [], "source": [ "pass" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "function" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(f)" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None\n" ] } ], "source": [ "r = f()\n", "print(r)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Эта функция более полезна: она имеет параметр и что-то возвращает." ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(x):\n", " return x + 1" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, 2.0)" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1), f(1.0)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "Can't convert 'int' object to str implicitly", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'abc'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mf\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: Can't convert 'int' object to str implicitly" ] } ], "source": [ "f('abc')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если у функции много параметров, то возникает желание вызывать её попроще в наиболее часто встречающихся случаях. Для этого в операторе `def` можно задать значения некоторых параметров по умолчанию (они должны размещаться в конце списка параметров). При вызове необходимо указать все обязательные параметры (у которых нет значений по умолчанию), а необязательные можно и не указывать. Если при вызове указывать параметры в виде `имя=значение`, то это можно делать в любом порядке. Это гораздо удобнее, чем вспоминать, является данный параметр восьмым или девятым при вызове какой-нибудь сложной функции. Обратите внимание, что в конструкции `имя=значение` не ставятся пробелы между символом `=`." ] }, { "cell_type": "code", "execution_count": 69, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(x, a=0, b='b'):\n", " print(x, ' ', a, ' ', b)" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0 0 b\n" ] } ], "source": [ "f(1.0)" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0 1 b\n" ] } ], "source": [ "f(1.0, 1)" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0 0 a\n" ] } ], "source": [ "f(1.0, b='a')" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0 2 a\n" ] } ], "source": [ "f(1.0, b='a', a=2)" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.0 2 b\n" ] } ], "source": [ "f(a=2, x=2.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Переменные, использующиеся в функции, являются локальными. Присваивание им не меняет значений глобальных переменных с такими же именами." ] }, { "cell_type": "code", "execution_count": 75, "metadata": { "collapsed": true }, "outputs": [], "source": [ "a = 1" ] }, { "cell_type": "code", "execution_count": 76, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f():\n", " a = 2\n", " return a" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f()" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если в функции нужно использовать какие-нибудь глобальные переменные, их нужно описать как `global`." ] }, { "cell_type": "code", "execution_count": 79, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f():\n", " global a\n", " a = 2\n", " return a" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f()" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Пространство имён устанавливает соответствие между именами переменных и объектами - их значениями. Есть пространство имён локальных переменных функции, пространство имён глобальных переменных программы и пространство имён встроенных функций языка питон. Для реализации пространств имён используются словари.\n", "\n", "Если функции передаётся в качестве аргумента какой-нибудь изменяемый объект, и функция его изменяет, то это изменение будет видно снаружи после этого вызова. Мы уже обсуждали эту ситуацию, когда две переменные (в данном случае глобальная переменная и параметр функции) указывают на один и тот же изменяемый объект объект." ] }, { "cell_type": "code", "execution_count": 82, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(x, l):\n", " l.append(x)\n", " return l" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 0]" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l = [1, 2, 3]\n", "f(0, l)" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 0]" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если в качестве значения какого-нибудь параметра по умолчанию используется изменяемый объект, то это может приводить к неожиданным последствиям. В данном случае исполнение определения функции приводит к созданию двух объектов: собственно функции и объекта-списка, первоначально пустого, который используется для инициализации параметра функции при вызове. Функция изменяет этот объект. При следующем вызове он опять используется для инициализации параметра, но его значение уже изменилось." ] }, { "cell_type": "code", "execution_count": 85, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(x, l=[]):\n", " l.append(x)\n", " return l" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0]" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(0)" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1]" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1)" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2]" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Чтобы избежать таких сюрпризов, в качестве значений по умолчанию лучше использовать только неизменяемые объекты." ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [], "source": [ "def f(x, l=None):\n", " if l is None:\n", " l = []\n", " l.append(x)\n", " return l" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0]" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(0)" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1]" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1)" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2]" ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(2, [0, 1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Эта функция имеет один обязательный параметр плюс произвольное число необязательных. При вызове все такие дополнительные аргументы объединяются в кортеж, который функция может использовать по своему усмотрению." ] }, { "cell_type": "code", "execution_count": 93, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(x, *l):\n", " print(x, ' ', l)" ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 ()\n" ] } ], "source": [ "f(0)" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 (1,)\n" ] } ], "source": [ "f(0, 1)" ] }, { "cell_type": "code", "execution_count": 96, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 (1, 2)\n" ] } ], "source": [ "f(0, 1, 2)" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 (1, 2, 3)\n" ] } ], "source": [ "f(0, 1, 2, 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Звёздочку можно использовать и при вызове функции. Можно заранее построить список (или кортеж) аргументов, а потом вызвать функцию с этими аргументами." ] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 (2, 0, 'a', 'b')\n" ] } ], "source": [ "l=[1, 2]\n", "c=('a', 'b')\n", "f(*l, 0, *c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Такую распаковку из списков и кортежей можно использовать не только при вызове функции, но и при построении списка или кортежа." ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 0, 'a', 'b')" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(*l, 0, *c)" ] }, { "cell_type": "code", "execution_count": 100, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 0, 'a', 'b']" ] }, "execution_count": 100, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[*l, 0, *c]" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3]" ] }, "execution_count": 101, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[*l, 3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Эта функция имеет два обязательных параметра плюс произвольное число необязательных ключевых параметров. При вызове они должны задаваться в виде `имя=значение`. Они собираются в словарь, который функция может использовать по своему усмотрению." ] }, { "cell_type": "code", "execution_count": 102, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(x, y, **d):\n", " print(x, ' ', y, ' ', d)" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 {'foo': 2, 'bar': 3}\n" ] } ], "source": [ "f(0, 1, foo=2, bar=3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Двойную звёздочку можно использовать и при вызове функции. Можно заранее построить словарь аргументов, сопоставляющий значения именам параметров, а потом вызвать функцию с этими ключевыми аргументами." ] }, { "cell_type": "code", "execution_count": 104, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 {'foo': 2, 'bar': 3}\n" ] } ], "source": [ "d={'foo': 2, 'bar': 3}\n", "f(0, 1, **d)" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 {'foo': 2, 'bar': 3}\n" ] } ], "source": [ "d['x'] = 0\n", "d['y'] = 1\n", "f(**d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Вот любопытный способ построить словарь с ключами-строками." ] }, { "cell_type": "code", "execution_count": 106, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(**d):\n", " return d" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'x': 0, 'y': 1, 'z': 2}" ] }, "execution_count": 107, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(x=0, y=1, z=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Двойную звёздочку можно использовать не только при вызове функции, но и при построении словаря." ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0: 'a', 1: 'b', 2: 'c'}" ] }, "execution_count": 108, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d={0: 'a', 1: 'b'}\n", "{**d, 2: 'c'}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Вот простой способ объединить два словаря." ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0: 'a', 1: 'b', 2: 'c', 3: 'd'}" ] }, "execution_count": 109, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d1 = {0: 'a', 1: 'b'}\n", "d2 = {2: 'c', 3: 'd'}\n", "{**d1, **d2}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если один и тот же ключ встречается несколько раз, следующее значение затирает предыдущее." ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0: 'a', 1: 'B', 2: 'C', 3: 'd'}" ] }, "execution_count": 110, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d2 = {1: 'B', 2: 'C'}\n", "{**d1, 3: 'D', **d2, 3: 'd'}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Это наиболее общий вид списка параметров функции. Сначала идут обязательные параметры (в данном случае два), затем произвольное число необязательных (при вызове они будут объединены в кортеж), а затем произвольное число ключевых параметров (при вызове они будут объединены в словарь)." ] }, { "cell_type": "code", "execution_count": 111, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(x, y, *l, **d):\n", " print(x, ' ', y, ' ', l, ' ', d)" ] }, { "cell_type": "code", "execution_count": 112, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 (2, 3) {'foo': 4, 'bar': 5}\n" ] } ], "source": [ "f(0, 1, 2, 3, foo=4, bar=5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В питоне функции являются гражданами первого сорта. Они могут присутствовать везде, где допустимы объекты других типов - среди элементов списков, значений в словарях и т.д." ] }, { "cell_type": "code", "execution_count": 113, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f0(x):\n", " return x + 2" ] }, { "cell_type": "code", "execution_count": 114, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f1(x):\n", " return 2 * x" ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[, ]" ] }, "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l = [f0, f1]\n", "l" ] }, { "cell_type": "code", "execution_count": 116, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4.0" ] }, "execution_count": 116, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 2.0\n", "n = 1\n", "l[n](x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если Вы пишете функцию не для того, чтобы один раз её вызвать и навсегда забыть, то нужна документация, объясняющая, что эта функция делает. Для этого сразу после строчки `def` пишется строка. Она называется док-строкой, и сохраняется при трансляции исходного текста на питоне в байт-код (в отличие от комментариев, которые при этом отбрасываются). Обычно эта строка заключается в тройные кавычки и занимает несколько строчек. Док-строка доступна как атрибут `__doc__` функции, и используется функцией `help`. Вот пример культурно написанной функции, вычисляющей $n$-е число Фибоначчи.\n", "\n", "Для проверки типов аргументов, переданных функции, удобно использовать оператор `assert`. Если условие в нём истинно, всё в порядке, и он ничего не делает; если же оно ложно, выдаётся сообщение об ошибке." ] }, { "cell_type": "code", "execution_count": 117, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def fib(n):\n", " '''вычисляет n-е число Фибоначчи'''\n", " \n", " assert type(n) is int and n>0\n", " \n", " if n <= 2:\n", " return 1\n", " \n", " x, y = 1, 1\n", " for i in range(n - 2):\n", " x, y = y, x + y\n", " \n", " return y" ] }, { "cell_type": "code", "execution_count": 118, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'вычисляет n-е число Фибоначчи'" ] }, "execution_count": 118, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fib.__doc__" ] }, { "cell_type": "code", "execution_count": 119, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function fib in module __main__:\n", "\n", "fib(n)\n", " вычисляет n-е число Фибоначчи\n", "\n" ] } ], "source": [ "help(fib)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В jupyter-ноутбуке к документации можно обращаться более удобным способом" ] }, { "cell_type": "code", "execution_count": 120, "metadata": { "collapsed": true }, "outputs": [], "source": [ "fib?" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 1, 2, 3, 5, 8, 13, 21, 34]" ] }, "execution_count": 121, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[fib(n) for n in range(1, 10)]" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "ename": "AssertionError", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfib\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mfib\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m'''вычисляет n-е число Фибоначчи'''\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0mint\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mn\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m<=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mAssertionError\u001b[0m: " ] } ], "source": [ "fib(-1)" ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "ename": "AssertionError", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfib\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mfib\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m'''вычисляет n-е число Фибоначчи'''\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0mint\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mn\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m<=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mAssertionError\u001b[0m: " ] } ], "source": [ "fib(2.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Некоторые полезные функции\n", "\n", "zip скрещивает два массива одной длины" ] }, { "cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(0, 0), (1, 2), (2, 4), (3, 6), (4, 8)]\n" ] } ], "source": [ "x = zip(range(5), range(0, 10, 2))\n", "print(list(x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "map применяет функию к каждому элементу массива" ] }, { "cell_type": "code", "execution_count": 125, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 1, 4, 9, 16]\n" ] } ], "source": [ "x = map(lambda tmp: tmp ** 2, range(5))\n", "print(list(x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "sorted --- сортировка" ] }, { "cell_type": "code", "execution_count": 126, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(9, 'a'), (7, 'a'), (4, 'a'), (5, 'k'), (4, 'n'), (3, 'n'), (3, 'n')]\n" ] } ], "source": [ "x = list(zip([7, 3, 4, 4, 5, 3, 9], ['a', 'n', 'n', 'a', 'k', 'n', 'a']))\n", "# сначала сортировка по букве по алфавиту, потом сортировка по убыванию по числу \n", "x = sorted(x, key=lambda element: (element[1], -element[0]))\n", "print(list(x))" ] } ], "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.3" } }, "nbformat": 4, "nbformat_minor": 1 }