{ "nbformat": 4, "nbformat_minor": 0, "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.9" }, "colab": { "name": "04_python_2.ipynb", "provenance": [] } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "re_i3X4ZLQj9" }, "source": [ "# Python для анализа данных\n", "\n", "## 1. Кортежи\n", "\n", "Кортежи (tuples) очень похожи на списки, но являются неизменяемыми. Как мы видели, использование изменяемых объектов может приводить к неприятным сюрпризам.\n", "\n", "Кортежи пишутся в круглых скобках. Если элементов $>1$ или 0, это не вызывает проблем. Но как записать кортеж с одним элементом? Конструкция `(x)` абсолютно легальна в любом месте любого выражения, и означает просто `x`. Чтобы избежать неоднозначности, кортеж с одним элементом `x` записывается в виде `(x,)`." ] }, { "cell_type": "code", "metadata": { "id": "dJZIzmCnLQkO", "outputId": "39e328f9-35dd-401f-fafe-7cd7b2462526" }, "source": [ "(1, 2, 3)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(1, 2, 3)" ] }, "metadata": { "tags": [] }, "execution_count": 1 } ] }, { "cell_type": "code", "metadata": { "id": "erEcGZsSLQkS", "outputId": "e36e43ef-a984-4e87-8c7f-f833e339db0e" }, "source": [ "()" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "()" ] }, "metadata": { "tags": [] }, "execution_count": 2 } ] }, { "cell_type": "code", "metadata": { "id": "vSt0aRAiLQkT", "outputId": "186293f8-314a-4c10-eef0-b30871e9123e" }, "source": [ "(1)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "1" ] }, "metadata": { "tags": [] }, "execution_count": 3 } ] }, { "cell_type": "code", "metadata": { "id": "uzrGftN0LQkU", "outputId": "174645d3-c0f7-444b-92a3-f8d719320fc7" }, "source": [ "(1,)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(1,)" ] }, "metadata": { "tags": [] }, "execution_count": 3 } ] }, { "cell_type": "markdown", "metadata": { "id": "6NXlhNqHLQkV" }, "source": [ "Скобки ставить не обязательно, если кортеж — единственная вещь в правой части присваивания." ] }, { "cell_type": "code", "metadata": { "id": "bm1Oco8bLQkW", "outputId": "28291ee6-ba92-4c17-e5bd-e07b0d139339" }, "source": [ "t = 1, 2, 3\n", "t" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(1, 2, 3)" ] }, "metadata": { "tags": [] }, "execution_count": 4 } ] }, { "cell_type": "markdown", "metadata": { "id": "Y_duRW1rLQkX" }, "source": [ "Работать с кортежами можно так же, как со списками. Нельзя только изменять их." ] }, { "cell_type": "code", "metadata": { "id": "I_NSnIR9LQkY", "outputId": "16d8cca5-194b-4783-fa2a-0f1314642977" }, "source": [ "len(t)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "3" ] }, "metadata": { "tags": [] }, "execution_count": 5 } ] }, { "cell_type": "code", "metadata": { "id": "G0Mz-zwgLQkZ", "outputId": "ec28bde3-4b64-4506-883b-49155dc26c7e" }, "source": [ "t[1]" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "2" ] }, "metadata": { "tags": [] }, "execution_count": 6 } ] }, { "cell_type": "code", "metadata": { "id": "ZMxNScP2LQka", "outputId": "201185ab-cac0-4bc8-ea85-3dc7eb5b2ee5" }, "source": [ "u = 4, 5\n", "t + u" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(1, 2, 3, 4, 5)" ] }, "metadata": { "tags": [] }, "execution_count": 7 } ] }, { "cell_type": "code", "metadata": { "id": "-NISHum6LQkb", "outputId": "a84dca0b-fe10-4eed-f3a3-775772b556d5" }, "source": [ "2 * u" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(4, 5, 4, 5)" ] }, "metadata": { "tags": [] }, "execution_count": 8 } ] }, { "cell_type": "markdown", "metadata": { "id": "clmJAJ-4LQkb" }, "source": [ "В левой части присваивания можно написать несколько переменных через запятую, а в правой кортеж. Это одновременное присваивание значений нескольким переменным." ] }, { "cell_type": "code", "metadata": { "id": "k8dfPPk6LQkc" }, "source": [ "x, y = 1, 2" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "5I1XOTMzLQkd", "outputId": "c42e4943-3833-4ad4-9b5f-5b725225598a" }, "source": [ "x" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "1" ] }, "metadata": { "tags": [] }, "execution_count": 5 } ] }, { "cell_type": "code", "metadata": { "id": "dd_PEMfSLQkd", "outputId": "b8f8dc4a-f6b3-4ba1-be66-c5fcac823d2c" }, "source": [ "y" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "2" ] }, "metadata": { "tags": [] }, "execution_count": 6 } ] }, { "cell_type": "markdown", "metadata": { "id": "6fAnMEV2LQke" }, "source": [ "Сначала вычисляется кортеж в правой части, исходя из *старых* значений переменных (до этого присваивания). Потом одновременно всем переменным присваиваются новые значения из этого кортежа. Поэтому так можно обменять значения двух переменных." ] }, { "cell_type": "code", "metadata": { "collapsed": true, "id": "sBa3vTZlLQkf" }, "source": [ "x, y = y, x" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "KtRJv7evLQkf", "outputId": "8489dcc8-eb78-46f0-9b7a-d09de971fa6a" }, "source": [ "x" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "1" ] }, "metadata": { "tags": [] }, "execution_count": 7 } ] }, { "cell_type": "code", "metadata": { "id": "NAOyEA9MLQkg", "outputId": "6943af9a-285b-439f-d99b-7e1c8e3bc222" }, "source": [ "y" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "2" ] }, "metadata": { "tags": [] }, "execution_count": 8 } ] }, { "cell_type": "markdown", "metadata": { "id": "uZkYaUsALQkh" }, "source": [ "Это проще, чем в других языках, где приходится использовать третью переменную.\n", "\n", "## 2. Множества\n", "\n", "В соответствии с математическими обозначениями, множества пишутся в фигурных скобках. Элемент может содержаться в множестве только один раз. Порядок элементов в множестве не имеет значения, поэтому питон их сортирует. Элементы множества могут быть любых типов." ] }, { "cell_type": "code", "metadata": { "id": "4oRhTeRYLQkh", "outputId": "4b5e19aa-6504-49ad-fe1d-ae4c009d34eb" }, "source": [ "s = {0, 1, 0, 5, 5, 1, 0}\n", "s" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0, 1, 5}" ] }, "metadata": { "tags": [] }, "execution_count": 15 } ] }, { "cell_type": "markdown", "metadata": { "id": "zShAyWvZLQki" }, "source": [ "Принадлежит ли элемент множеству?" ] }, { "cell_type": "code", "metadata": { "id": "JxXVxqodLQki", "outputId": "48eee5a3-14be-4064-86e7-16f58c05e201" }, "source": [ "1 in s, 2 in s, 1 not in s" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(True, False, False)" ] }, "metadata": { "tags": [] }, "execution_count": 16 } ] }, { "cell_type": "markdown", "metadata": { "id": "tKLv8EPpLQkj" }, "source": [ "Множество можно получить из списка, или строки, или любого объекта, который можно использовать в `for` цикле (итерабельного)." ] }, { "cell_type": "code", "metadata": { "id": "Uv3XUcvgLQkk", "outputId": "037b4275-6a1a-4f2d-fb06-679c08067bc9" }, "source": [ "l = [0, 1, 0, 5, 5, 1, 0]\n", "set(l)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0, 1, 5}" ] }, "metadata": { "tags": [] }, "execution_count": 17 } ] }, { "cell_type": "code", "metadata": { "id": "1JMvo6blLQkk", "outputId": "92c52d04-be9e-4bfc-b0c0-482e7008f4b9" }, "source": [ "set('абба')" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'а', 'б'}" ] }, "metadata": { "tags": [] }, "execution_count": 18 } ] }, { "cell_type": "markdown", "metadata": { "id": "TzIMM6M7LQkl" }, "source": [ "Как записать пустое множество? Только так." ] }, { "cell_type": "code", "metadata": { "id": "QiaXRCYdLQkl", "outputId": "87b93023-d31f-4bcd-e1c2-5873e00056fc" }, "source": [ "set()" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "set()" ] }, "metadata": { "tags": [] }, "execution_count": 19 } ] }, { "cell_type": "markdown", "metadata": { "id": "4qhQluNHLQkm" }, "source": [ "Дело в том, что в фигурных скобках в питоне пишутся также словари, что мы будем их обсуждать в следующем параграфе. Когда в них есть хоть один элемент, можно отличить словарь от множества. Но пустые фигурные скобки означают пустой словарь." ] }, { "cell_type": "code", "metadata": { "id": "-CGDyK2JLQku", "outputId": "95bc7b9b-41e9-4c11-c3b7-75c67217d434" }, "source": [ "{}" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{}" ] }, "metadata": { "tags": [] }, "execution_count": 20 } ] }, { "cell_type": "markdown", "metadata": { "id": "b922TB4lLQkv" }, "source": [ "Работать с множествами можно как со списками." ] }, { "cell_type": "code", "metadata": { "id": "og5VEleuLQkw", "outputId": "3fb2e628-227f-4255-bb95-d80e25edfb5c" }, "source": [ "len(s)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "3" ] }, "metadata": { "tags": [] }, "execution_count": 21 } ] }, { "cell_type": "code", "metadata": { "id": "JaznbxcNLQkw", "outputId": "e7b2733c-1221-4800-9e26-1ee99ab8bb9f" }, "source": [ "for x in s:\n", " print(x)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "0\n", "1\n", "5\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "4f5aaGSTLQkx" }, "source": [ "Это генератор множества (set comprehension)." ] }, { "cell_type": "code", "metadata": { "id": "Su8YI3EZLQkx", "outputId": "ca353f8c-2872-411d-b87c-70a5a8f51842" }, "source": [ "{i for i in range(5)}" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0, 1, 2, 3, 4}" ] }, "metadata": { "tags": [] }, "execution_count": 23 } ] }, { "cell_type": "markdown", "metadata": { "id": "Im1mqGbALQkx" }, "source": [ "Объединение множеств." ] }, { "cell_type": "code", "metadata": { "id": "tIffitJOLQky", "outputId": "7c7c22c4-ba19-4bb6-b273-9354c428680a" }, "source": [ "s2 = s | {2, 5}\n", "s2" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0, 1, 2, 5}" ] }, "metadata": { "tags": [] }, "execution_count": 24 } ] }, { "cell_type": "markdown", "metadata": { "id": "xfAY6rsZLQky" }, "source": [ "Проверка того, является ли одно множество подмножеством другого." ] }, { "cell_type": "code", "metadata": { "id": "hN9X0fBsLQky", "outputId": "52f65846-7c59-4667-e7a8-1b6dcc93cb80" }, "source": [ "s < s2, s > s2, s <= s2, s >= s2" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(True, False, True, False)" ] }, "metadata": { "tags": [] }, "execution_count": 25 } ] }, { "cell_type": "markdown", "metadata": { "id": "AyVmXNN8LQkz" }, "source": [ "Пересечение." ] }, { "cell_type": "code", "metadata": { "id": "0CJYtjDtLQkz", "outputId": "d9e1d56e-2501-4a8d-b3de-ed6c573dc544" }, "source": [ "s2 & {1, 2, 3}" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{1, 2}" ] }, "metadata": { "tags": [] }, "execution_count": 26 } ] }, { "cell_type": "markdown", "metadata": { "id": "fda_Au_JLQk0" }, "source": [ "Разность и симметричная разность." ] }, { "cell_type": "code", "metadata": { "id": "6S2DpE3wLQk0", "outputId": "b35d6080-be55-4c45-9e56-c321cd1625a0" }, "source": [ "s2 - {1,3,5}" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0, 2}" ] }, "metadata": { "tags": [] }, "execution_count": 27 } ] }, { "cell_type": "code", "metadata": { "id": "xbMifUn2LQk0", "outputId": "c7bb2d57-a84b-4b35-81b8-8aa19f595939" }, "source": [ "s2 ^ {1,3,5}" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0, 2, 3}" ] }, "metadata": { "tags": [] }, "execution_count": 28 } ] }, { "cell_type": "markdown", "metadata": { "id": "7vA67Oz2LQk1" }, "source": [ "Множества (как и списки) являются изменяемыми объектами. Добавление элемента в множество и исключение из него." ] }, { "cell_type": "code", "metadata": { "id": "E7RL8lY4LQk1", "outputId": "dd07c5d0-d02e-4659-aa24-55ac2350cc13" }, "source": [ "s2.add(4)\n", "s2" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0, 1, 2, 4, 5}" ] }, "metadata": { "tags": [] }, "execution_count": 29 } ] }, { "cell_type": "code", "metadata": { "id": "F8acSneGLQk2", "outputId": "8a362142-561f-459c-bdc7-5d13f182905d" }, "source": [ "s2.remove(1)\n", "s2" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0, 2, 4, 5}" ] }, "metadata": { "tags": [] }, "execution_count": 30 } ] }, { "cell_type": "markdown", "metadata": { "id": "No_c7gcVLQk2" }, "source": [ "Как и в случае `+=`, можно скомбинировать теоретико-множественную операцию с присваиванием." ] }, { "cell_type": "code", "metadata": { "id": "wTi7hE2yLQk3", "outputId": "8c884272-25e0-4d5c-8970-e494340f87f4" }, "source": [ "s2 |= {1, 2}\n", "s2" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0, 1, 2, 4, 5}" ] }, "metadata": { "tags": [] }, "execution_count": 31 } ] }, { "cell_type": "markdown", "metadata": { "id": "NvkeyLrJLQk3" }, "source": [ "Приведенные выше операции можно записывать и в другом стиле" ] }, { "cell_type": "code", "metadata": { "id": "qlFEHHDlLQk4", "outputId": "0f23693b-68a0-428c-c1d5-380496f124b6" }, "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])))" ], "execution_count": null, "outputs": [ { "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" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "BMelKryWLQk4" }, "source": [ "Существуют также неизменяемые множества. Этот тип данных называется `frozenset`. Операции над такими множествами подобны обычным, только невозможно изменять их, а всего лишь добавлять и исключать элементы.\n", "\n", "## 3. Словари\n", "\n", "Словарь содержит пары ключ — значение, причем порядо значений несущественен. Это один из наиболее полезных и часто используемых типов данных в питоне." ] }, { "cell_type": "code", "metadata": { "id": "2wQPvBGrLQk5", "outputId": "a2f00c8b-e1be-4f17-ee58-b4aa1910f429" }, "source": [ "d = {'one': 1, 'two': 2, 'three': 3}\n", "d" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'one': 1, 'two': 2, 'three': 3}" ] }, "metadata": { "tags": [] }, "execution_count": 9 } ] }, { "cell_type": "markdown", "metadata": { "id": "6xejC7UcLQk5" }, "source": [ "Можно узнать значение, соответствующее некоторому ключу. Словари реализованы как хэш-таблицы, так что поиск даже в больших словарях очень эффективен. В языках низкого уровня (например, C) для построения хэш-таблиц требуется использовать внешние библиотеки и писать заметное количество кода. В скриптовых языках (perl, python, php) они уже встроены в язык, и использовать их очень легко." ] }, { "cell_type": "code", "metadata": { "id": "Hkngmx3DLQk7", "outputId": "b5760fcb-d2e1-4d40-972a-2bde021346f2" }, "source": [ "d['two']" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "2" ] }, "metadata": { "tags": [] }, "execution_count": 10 } ] }, { "cell_type": "code", "metadata": { "id": "ch9le6vFLQk7", "outputId": "8a636a58-51c9-4867-dfff-44336ade965b" }, "source": [ "d['four']" ], "execution_count": null, "outputs": [ { "output_type": "error", "ename": "KeyError", "evalue": "'four'", "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[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mKeyError\u001b[0m: 'four'" ] } ] }, { "cell_type": "markdown", "metadata": { "id": "qxgk1wuBLQk7" }, "source": [ "Можно проверить, есть ли в словаре данный ключ." ] }, { "cell_type": "code", "metadata": { "id": "gPqdL7uiLQk8", "outputId": "797b4f24-1049-45f5-8b29-e059498d4d17" }, "source": [ "'one' in d, 'four' in d" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(True, False)" ] }, "metadata": { "tags": [] }, "execution_count": 12 } ] }, { "cell_type": "markdown", "metadata": { "id": "5SL7EINBLQk8" }, "source": [ "Можно присваивать значения как имеющимся ключам, так и отсутствующим (они добавятся к словарю)." ] }, { "cell_type": "code", "metadata": { "id": "RALEXwCuLQk8", "outputId": "f707a83a-ac47-41c6-974e-d90c43a94c59" }, "source": [ "d['one'] =- 1\n", "d" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'one': -1, 'two': 2, 'three': 3}" ] }, "metadata": { "tags": [] }, "execution_count": 13 } ] }, { "cell_type": "code", "metadata": { "id": "7VQvPmMuLQk9", "outputId": "5566361c-ef6a-4383-9542-9be8f611e54b" }, "source": [ "d['four'] = 4\n", "d" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'one': -1, 'two': 2, 'three': 3, 'four': 4}" ] }, "metadata": { "tags": [] }, "execution_count": 14 } ] }, { "cell_type": "markdown", "metadata": { "id": "l3bCqLwyLQk9" }, "source": [ "Длина — число ключей в словаре." ] }, { "cell_type": "code", "metadata": { "id": "NfiVwPMVLQk9", "outputId": "e897afc5-0766-4c88-86be-f54496600cda" }, "source": [ "len(d)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "4" ] }, "metadata": { "tags": [] }, "execution_count": 15 } ] }, { "cell_type": "markdown", "metadata": { "id": "5p6fvXRnLQk9" }, "source": [ "Можно удалить ключ из словаря." ] }, { "cell_type": "code", "metadata": { "id": "3-4fOJi0LQk-", "outputId": "cf1901a7-74bd-490e-a2fa-d646855f6317" }, "source": [ "del d['two']\n", "d" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'one': -1, 'three': 3, 'four': 4}" ] }, "metadata": { "tags": [] }, "execution_count": 16 } ] }, { "cell_type": "markdown", "metadata": { "id": "8IuAtKMpLQk-" }, "source": [ "Метод `get`, если он будет вызван с отсутствующим ключом, не приводит к ошибке, а возвращает специальный объект `None`. Он используется всегда, когда необходимо указать, что объект отсутствует. В какой-то мере он аналогичен `null` в C. Если передать методу `get` второй аргумент — значение по умолчанию, то будет возвращаться это значение, а не `None`." ] }, { "cell_type": "code", "metadata": { "id": "oB4SRukCLQk-", "outputId": "c8112d73-4225-451b-9dd9-50da684b6578" }, "source": [ "d.get('one'), d.get('five')" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(-1, None)" ] }, "metadata": { "tags": [] }, "execution_count": 17 } ] }, { "cell_type": "code", "metadata": { "id": "7usjfDVLLQk_", "outputId": "3072fe5d-ad81-4265-f860-d80a1190471a" }, "source": [ "d.get('one', 0), d.get('five', 0)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(-1, 0)" ] }, "metadata": { "tags": [] }, "execution_count": 18 } ] }, { "cell_type": "markdown", "metadata": { "id": "vDRsFB8zLQk_" }, "source": [ "Словари обычно строят последовательно: начинают с пустого словаря, а затем добавляют ключи со значениями." ] }, { "cell_type": "code", "metadata": { "id": "1Zp2P7RGLQk_", "outputId": "cd035eee-9a19-4bac-cb28-5e0f81015dea" }, "source": [ "d = {}\n", "d" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{}" ] }, "metadata": { "tags": [] }, "execution_count": 19 } ] }, { "cell_type": "code", "metadata": { "id": "brTwrczkLQk_", "outputId": "8da1d88e-2295-4834-caed-19329ded19e7" }, "source": [ "d['zero'] = 0\n", "d" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'zero': 0}" ] }, "metadata": { "tags": [] }, "execution_count": 20 } ] }, { "cell_type": "code", "metadata": { "id": "H2zaLQfsLQlA", "outputId": "b05d1e7d-4b27-47a6-eb8c-151196dfd3da" }, "source": [ "d['one'] = 1\n", "d" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'zero': 0, 'one': 1}" ] }, "metadata": { "tags": [] }, "execution_count": 21 } ] }, { "cell_type": "markdown", "metadata": { "id": "e2MQ83NXLQlA" }, "source": [ "А это генератор словаря (dictionary comprehension)." ] }, { "cell_type": "code", "metadata": { "id": "EyuEFsbvLQlA", "outputId": "5bff050a-3f7f-449b-ab9f-b06d0d0dc27d" }, "source": [ "d = {i: i ** 2 for i in range(5)}\n", "d" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}" ] }, "metadata": { "tags": [] }, "execution_count": 22 } ] }, { "cell_type": "markdown", "metadata": { "id": "uhkyEBTlLQlB" }, "source": [ "Ключами могут быть любые неизменяемые объекты, например, целые числа, строки, кортежи." ] }, { "cell_type": "code", "metadata": { "id": "UCTWcsuaLQlB", "outputId": "9bba5c24-a54c-437e-af49-3144df3c7fe8" }, "source": [ "d = {}\n", "d[0, 0] = 1\n", "d[0, 1] = 0\n", "d[1, 0] = 0\n", "d[1, 1] = -1\n", "d" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{(0, 0): 1, (0, 1): 0, (1, 0): 0, (1, 1): -1}" ] }, "metadata": { "tags": [] }, "execution_count": 23 } ] }, { "cell_type": "code", "metadata": { "id": "sn99MwCULQlB", "outputId": "f263e98a-487e-403f-a036-54e2d179d4df" }, "source": [ "d[0, 0] + d[1, 1]" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "0" ] }, "metadata": { "tags": [] }, "execution_count": 24 } ] }, { "cell_type": "markdown", "metadata": { "id": "OGuvLHEsLQlB" }, "source": [ "Словари, подобно спискам, можно использовать в `for` циклах. Перебираются имеющиеся в словаре ключи, причем в каком-то непредсказуемом порядке." ] }, { "cell_type": "code", "metadata": { "id": "ECA-RJDhLQlC", "outputId": "7fe0fb6a-49de-40fb-e205-ba0f96c5dadd" }, "source": [ "d = {'one': 1, 'two': 2, 'three': 3}\n", "for x in d:\n", " print(x, ' ', d[x])" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "one 1\n", "two 2\n", "three 3\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "lr4PhFW6LQlC" }, "source": [ "Метод `keys` возвращает список ключей, метод `values` — список соответствующих значений (в том же порядке), а метод `items` — список пар (ключ, значение). Точнее говоря, это не списки, а некоторые объекты, которые можно использовать в `for` циклах или превратить в списки функцией `list`. Если хочется написать цикл по упорядоченному списку ключей, то можно использовать `sorted(d.keys))`." ] }, { "cell_type": "code", "metadata": { "id": "kGFFPas3LQlC", "outputId": "8cecac4a-fef5-445d-b773-88273585a73d" }, "source": [ "d.keys(), d.values(), d.items()" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(dict_keys(['one', 'two', 'three']),\n", " dict_values([1, 2, 3]),\n", " dict_items([('one', 1), ('two', 2), ('three', 3)]))" ] }, "metadata": { "tags": [] }, "execution_count": 50 } ] }, { "cell_type": "code", "metadata": { "id": "lL_AmxaoLQlC", "outputId": "c8b0e3c5-ce54-492a-abbf-e00315db0292" }, "source": [ "for x in sorted(d.keys()):\n", " print(x, ' ', d[x])" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "one 1\n", "three 3\n", "two 2\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "_Dp3q3P3LQlD", "outputId": "4af8ea88-ec71-4f08-c665-e2bbcb4fd840" }, "source": [ "for x, y in d.items():\n", " print(x, ' ', y)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "one 1\n", "two 2\n", "three 3\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "hEVxQPs6LQlD" }, "source": [ "del x, y" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "0BqjzoV5LQlD" }, "source": [ "Что есть истина? И что есть ложь? Подойдём к этому философскому вопросу экспериментально." ] }, { "cell_type": "code", "metadata": { "id": "_V3Va2M2LQlE", "outputId": "efabdc2b-0275-4f22-df74-c5c530961c8e" }, "source": [ "bool(False), bool(True)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(False, True)" ] }, "metadata": { "tags": [] }, "execution_count": 29 } ] }, { "cell_type": "code", "metadata": { "id": "YYQ_uj0qLQlE", "outputId": "3247608b-1c1d-4bdc-ce3b-06f53d4a7b67" }, "source": [ "bool(None)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "False" ] }, "metadata": { "tags": [] }, "execution_count": 30 } ] }, { "cell_type": "code", "metadata": { "id": "eFm5jbtkLQlE", "outputId": "dc7b345c-cb33-421d-ba2a-01698520ceb9" }, "source": [ "bool(0), bool(123)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(False, True)" ] }, "metadata": { "tags": [] }, "execution_count": 31 } ] }, { "cell_type": "code", "metadata": { "id": "u4lOgSbCLQlE", "outputId": "033dfa80-003e-45db-e101-d551c880d635" }, "source": [ "bool(''), bool(' ')" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(False, True)" ] }, "metadata": { "tags": [] }, "execution_count": 32 } ] }, { "cell_type": "code", "metadata": { "id": "pET0pKrxLQlF", "outputId": "ca1368be-e745-4472-e7df-b0243c1ccfee" }, "source": [ "bool([]), bool([0])" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(False, True)" ] }, "metadata": { "tags": [] }, "execution_count": 58 } ] }, { "cell_type": "code", "metadata": { "id": "qNytY-T3LQlF", "outputId": "01fa341c-dd44-4059-93e0-8fdf776e4860" }, "source": [ "bool(set()), bool({0})" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(False, True)" ] }, "metadata": { "tags": [] }, "execution_count": 59 } ] }, { "cell_type": "code", "metadata": { "id": "lvMzAmdWLQlF", "outputId": "d8324c8e-be4a-4b6c-a622-e87bff683604" }, "source": [ "bool({}), bool({0: 0})" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(False, True)" ] }, "metadata": { "tags": [] }, "execution_count": 60 } ] }, { "cell_type": "code", "metadata": { "id": "NdwaldQ9LQlG", "outputId": "288da96e-9390-4267-e4e9-a31f600951d6" }, "source": [ "bool(0.0)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "True" ] }, "metadata": { "tags": [] }, "execution_count": 34 } ] }, { "cell_type": "markdown", "metadata": { "id": "zEnUXGpALQlG" }, "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)" ] }, "metadata": { "tags": [] }, "execution_count": 36 } ] }, { "cell_type": "code", "metadata": { "id": "KWQ8BcTeLQlI" }, "source": [ "pass" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "B-OSE-YiLQlI", "outputId": "2487762a-1605-4a70-c438-881818a7631a" }, "source": [ "type(f)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "function" ] }, "metadata": { "tags": [] }, "execution_count": 38 } ] }, { "cell_type": "code", "metadata": { "id": "ri7sOh8YLQlI", "outputId": "33fc600f-ec81-4168-ce1e-ab9106ac3081" }, "source": [ "r = f()\n", "print(r)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "None\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "IimfzphmLQlJ" }, "source": [ "Эта функция более полезна: она имеет параметр и что-то возвращает." ] }, { "cell_type": "code", "metadata": { "id": "tioFTc-lLQlJ" }, "source": [ "def f(x):\n", " return x + 1" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "jdM-ygeOLQlJ", "outputId": "b2214b82-a43b-4e3e-ae0c-e1055cc26074" }, "source": [ "f(1), f(1.0)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(2, 2.0)" ] }, "metadata": { "tags": [] }, "execution_count": 41 } ] }, { "cell_type": "code", "metadata": { "id": "PkmHfbEKLQlJ", "outputId": "c6c1b779-a4c7-441b-fb4e-f45bc0c56fbc" }, "source": [ "f('abc')" ], "execution_count": null, "outputs": [ { "output_type": "error", "ename": "TypeError", "evalue": "must be str, not int", "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[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[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[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: must be str, not int" ] } ] }, { "cell_type": "markdown", "metadata": { "id": "y8wsE_eeLQlK" }, "source": [ "Если у функции много параметров, то возникает желание вызывать её попроще в наиболее часто встречающихся случаях. Для этого в операторе `def` можно задать значения некоторых параметров по умолчанию, которые должны размещаться в конце списка параметров. При вызове необходимо указать все обязательные параметры, у которых нет значений по умолчанию, а необязательные можно и не указывать. Если при вызове указывать параметры в виде `имя=значение`, то это можно делать в любом порядке. Это гораздо удобнее, чем вспоминать, является данный параметр восьмым или девятым при вызове какой-нибудь сложной функции. Обратите внимание, что в конструкции `имя=значение` не ставятся пробелы между символом `=`." ] }, { "cell_type": "code", "metadata": { "collapsed": true, "id": "LhAEtIzcLQlK" }, "source": [ "def f(x, a=0, b='b'):\n", " print(x, ' ', a, ' ', b)" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "ykMbaYwZLQlK", "outputId": "87f18ee9-68d3-4389-ce65-c1c7da538d92" }, "source": [ "f(1.0)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "1.0 0 b\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "KuCwH72mLQlK", "outputId": "965dcafc-b6e9-4c55-c555-37c0c96c1c9c" }, "source": [ "f(1.0, 1)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "1.0 1 b\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "OkrnWKK3LQlL", "outputId": "5f40bc61-ddbe-46f0-a7ac-d8ae9b512298" }, "source": [ "f(1.0, b='a')" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "1.0 0 a\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "-XEP5zEeLQlL", "outputId": "f5afab68-1516-4dc0-b951-1707fc4bc329" }, "source": [ "f(1.0, b='a', a=2)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "1.0 2 a\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "xWMi7eX5LQlL", "outputId": "d51c5afa-8752-4dba-a0b1-aed709fc5b1c" }, "source": [ "f(a=2, x=2.0)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "2.0 2 b\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "vXP5XvBQLQlM" }, "source": [ "Переменные, использующиеся в функции, являются локальными. Присваивание им не меняет значений глобальных переменных с такими же именами." ] }, { "cell_type": "code", "metadata": { "id": "ZuqLHeDULQlM" }, "source": [ "a = 1" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "O6t6do5DLQlM" }, "source": [ "def f():\n", " a = 2\n", " return a" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "_j43rsBDLQlM", "outputId": "46a17aa1-ac94-4297-d6e7-dcab238c469e" }, "source": [ "f()" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "2" ] }, "metadata": { "tags": [] }, "execution_count": 45 } ] }, { "cell_type": "code", "metadata": { "id": "bWQjxgBJLQlN", "outputId": "5ee84a1c-c566-4796-80b6-aeda4de96619" }, "source": [ "a" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "1" ] }, "metadata": { "tags": [] }, "execution_count": 46 } ] }, { "cell_type": "markdown", "metadata": { "id": "PiZEZQ-yLQlN" }, "source": [ "Если в функции нужно использовать какие-нибудь глобальные переменные, их нужно описать как `global`." ] }, { "cell_type": "code", "metadata": { "id": "hruU72TjLQlO" }, "source": [ "def f():\n", " global a\n", " a = 2\n", " return a" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "uXLplbtDLQlO", "outputId": "ff0a3683-4e68-428c-f47c-1ee83f88c0b7" }, "source": [ "f()" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "2" ] }, "metadata": { "tags": [] }, "execution_count": 48 } ] }, { "cell_type": "code", "metadata": { "id": "klBKELWeLQlO", "outputId": "434987b8-cb3d-46c8-9e67-e95bd155f25a" }, "source": [ "a" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "2" ] }, "metadata": { "tags": [] }, "execution_count": 49 } ] }, { "cell_type": "markdown", "metadata": { "id": "4R_rvy0_LQlP" }, "source": [ "Пространство имён устанавливает соответствие между именами переменных и объектами — их значениями. Есть пространство имён локальных переменных функции, пространство имён глобальных переменных программы и пространство имён встроенных функций языка питон. Для реализации пространств имён используются словари.\n", "\n", "Если функции передаётся в качестве аргумента какой-нибудь изменяемый объект, и функция его изменяет, то это изменение будет видно снаружи после этого вызова. Мы уже обсуждали эту ситуацию, когда две переменные указывают на один и тот же изменяемый объект объект. В данном случае такими переменнями являются глобальная переменная и параметр функции" ] }, { "cell_type": "code", "metadata": { "id": "0aFoDbpFLQlP" }, "source": [ "def f(x, l):\n", " l.append(x)\n", " return l" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "8Go4i0KHLQlP", "outputId": "be71eeea-9190-46d0-bdd7-f30e56a45f1d" }, "source": [ "l = [1, 2, 3]\n", "f(0, l)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[1, 2, 3, 0]" ] }, "metadata": { "tags": [] }, "execution_count": 51 } ] }, { "cell_type": "code", "metadata": { "id": "nSgWyww4LQlP", "outputId": "fb55afca-ec52-4cbe-b93a-c851186f5cb7" }, "source": [ "l" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[1, 2, 3, 0]" ] }, "metadata": { "tags": [] }, "execution_count": 52 } ] }, { "cell_type": "markdown", "metadata": { "id": "FamWVIYvLQlQ" }, "source": [ "Если в качестве значения какого-нибудь параметра по умолчанию используется изменяемый объект, то это может приводить к неожиданным последствиям. В данном случае исполнение определения функции приводит к созданию двух объектов: собственно функции и объекта-списка, первоначально пустого, который используется для инициализации параметра функции при вызове. Функция изменяет этот объект. При следующем вызове он опять используется для инициализации параметра, но его значение уже изменилось." ] }, { "cell_type": "code", "metadata": { "id": "alRYPdJELQlQ" }, "source": [ "def f(x, l=[]):\n", " l.append(x)\n", " return l" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "K6JEGvd7LQlQ", "outputId": "f6afdb2c-73bd-4205-90ee-8b4585869433" }, "source": [ "f(0)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[0]" ] }, "metadata": { "tags": [] }, "execution_count": 54 } ] }, { "cell_type": "code", "metadata": { "id": "tm74sfNSLQlQ", "outputId": "815d8b04-17ae-4d73-e76b-47e010781b62" }, "source": [ "f(1)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[0, 1]" ] }, "metadata": { "tags": [] }, "execution_count": 55 } ] }, { "cell_type": "code", "metadata": { "id": "hT44ye1HLQlR", "outputId": "4455aada-ad08-430a-8cae-16ff237eff79" }, "source": [ "f(2)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[0, 1, 2]" ] }, "metadata": { "tags": [] }, "execution_count": 56 } ] }, { "cell_type": "markdown", "metadata": { "id": "KaOhDk_NLQlR" }, "source": [ "Чтобы избежать таких сюрпризов, в качестве значений по умолчанию лучше использовать только неизменяемые объекты." ] }, { "cell_type": "code", "metadata": { "id": "CS7jvza3LQlR" }, "source": [ "def f(x, l=None):\n", " if l is None:\n", " l = []\n", " l.append(x)\n", " return l" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "gBJHKXHxLQlR", "outputId": "97e92fc4-a8ca-48ed-d213-75ea34bcd7c0" }, "source": [ "f(0)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[0]" ] }, "metadata": { "tags": [] }, "execution_count": 58 } ] }, { "cell_type": "code", "metadata": { "id": "0oScVlviLQlS", "outputId": "edc27d0d-53e3-4d5a-86f0-1b5bbe4dd847" }, "source": [ "f(1)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[1]" ] }, "metadata": { "tags": [] }, "execution_count": 59 } ] }, { "cell_type": "code", "metadata": { "id": "tQTgkTqbLQlS", "outputId": "b1572af4-bca7-4b52-c3ce-a1d601455648" }, "source": [ "f(2, [0, 1])" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[0, 1, 2]" ] }, "metadata": { "tags": [] }, "execution_count": 60 } ] }, { "cell_type": "markdown", "metadata": { "id": "O2ebn-XFLQlS" }, "source": [ "Эта функция имеет один обязательный параметр плюс произвольное число необязательных. При вызове все такие дополнительные аргументы объединяются в кортеж, который функция может использовать по своему усмотрению." ] }, { "cell_type": "code", "metadata": { "id": "2IgRZAmkLQlT" }, "source": [ "def f(x, *l):\n", " print(x, ' ', l)" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "K_WcS-lBLQlT", "outputId": "5f8ceab3-88d2-4a16-c374-65a555e0746d" }, "source": [ "f(0)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "0 ()\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "5T9wx_GALQlT", "outputId": "048868d1-6ba8-4cfd-8403-ed2142b03ca7" }, "source": [ "f(0, 1)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "0 (1,)\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "ZWKh7TuPLQlT", "outputId": "d49ae01d-fddd-49e5-c836-acc751b409b0" }, "source": [ "f(0, 1, 2)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "0 (1, 2)\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "B5Dq-gh3LQlU", "outputId": "46b83ef8-c188-435f-db44-bb9096016082" }, "source": [ "f(0, 1, 2, 3)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "0 (1, 2, 3)\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "htaHaQyCLQlU" }, "source": [ "Звёздочку можно использовать и при вызове функции. Можно заранее построить список (или кортеж) аргументов, а потом вызвать функцию с этими аргументами." ] }, { "cell_type": "code", "metadata": { "id": "IhHfLoU9LQlU", "outputId": "8a51a391-3f98-419a-fa90-3503b0e0a0a8" }, "source": [ "l=[1, 2]\n", "c=('a', 'b')\n", "f(*l, 0, *c)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "1 (2, 0, 'a', 'b')\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "7PWyg7SfLQlU" }, "source": [ "Такую распаковку из списков и кортежей можно использовать не только при вызове функции, но и при построении списка или кортежа." ] }, { "cell_type": "code", "metadata": { "id": "9GdE37orLQlV", "outputId": "9b10756f-5bff-4db1-8acc-6f4753cac722" }, "source": [ "(*l, 0, *c)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(1, 2, 0, 'a', 'b')" ] }, "metadata": { "tags": [] }, "execution_count": 68 } ] }, { "cell_type": "code", "metadata": { "id": "tZwxW5ogLQlV", "outputId": "1c79c321-5886-4c5f-ee68-3dce0389fa6e" }, "source": [ "[*l, 0, *c]" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[1, 2, 0, 'a', 'b']" ] }, "metadata": { "tags": [] }, "execution_count": 69 } ] }, { "cell_type": "code", "metadata": { "id": "rsFiDW-7LQlV", "outputId": "6a84cac6-eede-4ae1-a9ff-cce79b4756cf" }, "source": [ "[*l, 3]" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[1, 2, 3]" ] }, "metadata": { "tags": [] }, "execution_count": 70 } ] }, { "cell_type": "markdown", "metadata": { "id": "Oye9O9yOLQlV" }, "source": [ "Эта функция имеет два обязательных параметра плюс произвольное число необязательных ключевых параметров. При вызове они должны задаваться в виде `имя=значение`. Они собираются в словарь, который функция может использовать по своему усмотрению." ] }, { "cell_type": "code", "metadata": { "id": "QF_IokdLLQlW" }, "source": [ "def f(x, y, **d):\n", " print(x, ' ', y, ' ', d)" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "B2EIRTLCLQlW", "outputId": "2703598d-40f0-444a-d926-bca74c1d04ce" }, "source": [ "f(0, 1, foo=2, bar=3)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "0 1 {'foo': 2, 'bar': 3}\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "C0-PWSMVLQlW" }, "source": [ "Двойную звёздочку можно использовать и при вызове функции. Можно заранее построить словарь аргументов, сопоставляющий значения именам параметров, а потом вызвать функцию с этими ключевыми аргументами." ] }, { "cell_type": "code", "metadata": { "id": "hHSZq4zALQlW", "outputId": "45d4d7d0-21d2-463f-9985-b64f6171f5e5" }, "source": [ "d={'foo': 2, 'bar': 3}\n", "f(0, 1, **d)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "0 1 {'foo': 2, 'bar': 3}\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "KWooSuxjLQlX", "outputId": "d64d0211-650c-4377-b12b-998f720b6b5b" }, "source": [ "d['x'] = 0\n", "d['y'] = 1\n", "f(**d)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "0 1 {'foo': 2, 'bar': 3}\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "tCl-5CYPLQlX" }, "source": [ "Вот любопытный способ построить словарь с ключами-строками." ] }, { "cell_type": "code", "metadata": { "id": "HJofVqZeLQlX" }, "source": [ "def f(**d):\n", " return d" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "9CKge7ToLQlX", "outputId": "251db420-dff2-4b28-cf5c-8b529f095956" }, "source": [ "f(x=0, y=1, z=2)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'x': 0, 'y': 1, 'z': 2}" ] }, "metadata": { "tags": [] }, "execution_count": 76 } ] }, { "cell_type": "markdown", "metadata": { "id": "rvu0hMBPLQlY" }, "source": [ "Двойную звёздочку можно использовать не только при вызове функции, но и при построении словаря." ] }, { "cell_type": "code", "metadata": { "id": "kS95lZafLQlY", "outputId": "cbf468c2-5bf1-4ed4-9622-b365c848de2a" }, "source": [ "d={0: 'a', 1: 'b'}\n", "{**d, 2: 'c'}" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0: 'a', 1: 'b', 2: 'c'}" ] }, "metadata": { "tags": [] }, "execution_count": 77 } ] }, { "cell_type": "markdown", "metadata": { "id": "MLz9C3PfLQlY" }, "source": [ "Вот простой способ объединить два словаря." ] }, { "cell_type": "code", "metadata": { "id": "9VYYUcAPLQlY", "outputId": "ac994190-a844-4b57-f196-af0b861d528d" }, "source": [ "d1 = {0: 'a', 1: 'b'}\n", "d2 = {2: 'c', 3: 'd'}\n", "{**d1, **d2}" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0: 'a', 1: 'b', 2: 'c', 3: 'd'}" ] }, "metadata": { "tags": [] }, "execution_count": 78 } ] }, { "cell_type": "markdown", "metadata": { "id": "tNXLj1HKLQlZ" }, "source": [ "Если один и тот же ключ встречается несколько раз, следующее значение затирает предыдущее." ] }, { "cell_type": "code", "metadata": { "id": "YdpyaXvTLQlZ", "outputId": "5871546b-6ec6-45f0-814d-32beb7d302b7" }, "source": [ "d2 = {1: 'B', 2: 'C'}\n", "{**d1, 3: 'D', **d2, 3: 'd'}" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0: 'a', 1: 'B', 3: 'd', 2: 'C'}" ] }, "metadata": { "tags": [] }, "execution_count": 79 } ] }, { "cell_type": "markdown", "metadata": { "id": "AIJDM-ItLQlZ" }, "source": [ "Это наиболее общий вид списка параметров функции. Сначала идут обязательные параметры (в данном случае два), далее произвольное число необязательных, причем при вызове они будут объединены в кортеж, а затем произвольное число ключевых параметров, причем при вызове они будут объединены в словарь." ] }, { "cell_type": "code", "metadata": { "id": "d44lGPZvLQlZ" }, "source": [ "def f(x, y, *l, **d):\n", " print(x, ' ', y, ' ', l, ' ', d)" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "3XlBkBfcLQla", "outputId": "1c036ecb-97fd-4954-b747-6cc394faaaae" }, "source": [ "f(0, 1, 2, 3, foo=4, bar=5)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "0 1 (2, 3) {'foo': 4, 'bar': 5}\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "B5tQYOp-LQla" }, "source": [ "В питоне функции являются гражданами первого сорта. Они могут присутствовать везде, где допустимы объекты других типов - среди элементов списков, значений в словарях и т.д." ] }, { "cell_type": "code", "metadata": { "id": "cYG4iNUNLQla" }, "source": [ "def f0(x):\n", " return x + 2" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "uVKjCVUyLQla" }, "source": [ "def f1(x):\n", " return 2 * x" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "hipw3e_3LQlb", "outputId": "be090f8f-5450-498b-afd8-d19e2864d962" }, "source": [ "l = [f0, f1]\n", "l" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[, ]" ] }, "metadata": { "tags": [] }, "execution_count": 85 } ] }, { "cell_type": "code", "metadata": { "id": "9yA60SnWLQlb", "outputId": "5636edb1-7d81-4771-8385-0abea97c4be2" }, "source": [ "x = 2.0\n", "n = 1\n", "l[n](x)" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "4.0" ] }, "metadata": { "tags": [] }, "execution_count": 86 } ] }, { "cell_type": "markdown", "metadata": { "id": "Sg34T5KwLQlb" }, "source": [ "Если Вы пишете функцию не для того, чтобы один раз её вызвать и навсегда забыть, то нужна документация, объясняющая, что эта функция делает. Для этого сразу после строчки `def` пишется строка. Она называется док-строкой, и сохраняется при трансляции исходного текста на питоне в байт-код, в отличие от комментариев, которые при этом отбрасываются. Обычно эта строка заключается в тройные кавычки и занимает несколько строчек. Док-строка доступна как атрибут `__doc__` функции, и используется функцией `help`. Вот пример культурно написанной функции, вычисляющей $n$-е число Фибоначчи.\n", "\n", "Для проверки типов аргументов, переданных функции, удобно использовать оператор `assert`. Если условие в нём истинно, всё в порядке, и он ничего не делает; если же оно ложно, выдаётся сообщение об ошибке." ] }, { "cell_type": "code", "metadata": { "id": "Pbp9X0pdLQlb" }, "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" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "jhRsI4AFLQlc", "outputId": "c56cc993-9451-479b-fece-0ab9a33c7a52" }, "source": [ "fib.__doc__" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "'вычисляет n-е число Фибоначчи'" ] }, "metadata": { "tags": [] }, "execution_count": 88 } ] }, { "cell_type": "code", "metadata": { "id": "WjFrkHSFLQlc", "outputId": "2bdec3ec-de60-47f0-849f-df1121d4d21c" }, "source": [ "help(fib)" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "Help on function fib in module __main__:\n", "\n", "fib(n)\n", " вычисляет n-е число Фибоначчи\n", "\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "WmPtrva1LQlc" }, "source": [ "В jupyter-ноутбуке к документации можно обращаться более удобным способом" ] }, { "cell_type": "code", "metadata": { "id": "jJqHSF2WLQld" }, "source": [ "fib?" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "RJVrt2fZLQld", "outputId": "ffa2753d-2415-4f70-e5d2-ae4faf21f6dc" }, "source": [ "[fib(n) for n in range(1, 10)]" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[1, 1, 2, 3, 5, 8, 13, 21, 34]" ] }, "metadata": { "tags": [] }, "execution_count": 91 } ] }, { "cell_type": "code", "metadata": { "id": "qaBH4hN6LQld", "outputId": "9ed51602-b62f-4735-9d75-53a3262cd56a" }, "source": [ "fib(-1)" ], "execution_count": null, "outputs": [ { "output_type": "error", "ename": "AssertionError", "evalue": "", "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[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[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[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[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mAssertionError\u001b[0m: " ] } ] }, { "cell_type": "code", "metadata": { "id": "Tz49da_gLQld", "outputId": "7bd3ad8a-cd75-4a27-a677-d8b0a420c4c4" }, "source": [ "fib(2.0)" ], "execution_count": null, "outputs": [ { "output_type": "error", "ename": "AssertionError", "evalue": "", "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[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[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[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[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mAssertionError\u001b[0m: " ] } ] }, { "cell_type": "markdown", "metadata": { "id": "3urv21jXLQle" }, "source": [ "## 5. Некоторые полезные функции\n", "\n", "Функция `zip` скрещивает два массива одной длины" ] }, { "cell_type": "code", "metadata": { "id": "F2dQr2OkLQle", "outputId": "efdf63ae-8baa-41ad-dbb8-3203718d035b" }, "source": [ "x = zip(range(5), range(0, 10, 2))\n", "print(list(x))" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "[(0, 0), (1, 2), (2, 4), (3, 6), (4, 8)]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "cpzZ53ppLQle" }, "source": [ "Функция `map` применяет функию к каждому элементу массива" ] }, { "cell_type": "code", "metadata": { "id": "vlrmDctoLQlf", "outputId": "feedf8af-1388-4412-b223-96c19406f07a" }, "source": [ "x = map(fib, range(1, 10))\n", "print(list(x))" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "[1, 1, 2, 3, 5, 8, 13, 21, 34]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "xyaGIduoLQlf" }, "source": [ "Функция `sorted` выполняет сортировку данныз" ] }, { "cell_type": "code", "metadata": { "id": "FL3IDG2xLQlf", "outputId": "409efcc4-442a-4d63-e932-d07b22003fac" }, "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))" ], "execution_count": null, "outputs": [ { "output_type": "stream", "text": [ "[(9, 'a'), (7, 'a'), (4, 'a'), (5, 'k'), (4, 'n'), (3, 'n'), (3, 'n')]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "j2xYdIxk8qLU" }, "source": [ "---\n", "\n", "При подготовке использованы материалы https://inp.nsk.su/~grozin/python/" ] } ] }