{ "cells": [ { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Вспомним, как работает параметр key при сортировке\n", "\n", "names = [\"Оля\", \"Юля\", \"Петя\", \"Маша\", \"Аня\", \"Света\"]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['Аня', 'Маша', 'Оля', 'Петя', 'Света', 'Юля']" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Сортируем просто лексикографически\n", "list(sorted(names))" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['Оля', 'Юля', 'Аня', 'Петя', 'Маша', 'Света']" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Пусть теперь надо отсортировать строки по их длине\n", "# Передадим в качестве параметра стандартную функцию len\n", "list(sorted(names, key=len))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['Аня', 'Оля', 'Юля', 'Маша', 'Петя', 'Света']" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Встоенная сортировка является стабильной:\n", "# порядок строк с одинаковой длиной не изменился\n", "\n", "# Пусть теперь нужно отсортировать строки сначала по длине,\n", "# а при равных длинах - лексикографически\n", "# Студенты на лекции предложили такой способ:\n", "# сначала сортируем лексикографически, а потом - стабильно по длине\n", "list(sorted(sorted(names), key=len))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['Аня', 'Оля', 'Юля', 'Маша', 'Петя', 'Света']" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Можно обойтись и одной сортировкой,\n", "# если в качестве ключа передавать функцию,\n", "# возвращающую по строке x пару из её длины и самой этой строки\n", "# Такие пары будут сами сравниваться лексикографически\n", "list(sorted(names, key=lambda x: (len(x), x)))" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['Высшей',\n", " 'Студенты',\n", " 'Факультета',\n", " 'компьютерных',\n", " 'наук',\n", " 'школы',\n", " 'экономики']" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Ещё пример: сортировка без учёта регистра\n", "# По умолчанию заглавные буквы идут раньше\n", "s = \"Студенты Факультета компьютерных наук Высшей школы экономики\"\n", "words = s.split(\" \")\n", "list(sorted(words))" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['Высшей',\n", " 'компьютерных',\n", " 'наук',\n", " 'Студенты',\n", " 'Факультета',\n", " 'школы',\n", " 'экономики']" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Будем при сортировке сравнивать строки в нижнем регистре\n", "list(sorted(words, key=str.lower))" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Вспомним теперь функции.\n", "# Напишем функцию проверки простоты числа\n", "def is_prime(x):\n", " if x <= 1:\n", " return False\n", " for d in range(2, int(x**0.5) + 1):\n", " if x % d == 0:\n", " return False\n", " return True" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 False\n", "1 False\n", "2 True\n", "3 True\n", "4 False\n", "5 True\n", "6 False\n", "7 True\n", "8 False\n", "9 False\n", "10 False\n", "11 True\n", "12 False\n", "13 True\n", "14 False\n" ] } ], "source": [ "for i in range(15):\n", " print(i, is_prime(i))" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Списковые выражения: описание элементов списка в общем виде\n", "[x**2 for x in range(15)]" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[(0, False),\n", " (1, False),\n", " (2, True),\n", " (3, True),\n", " (4, False),\n", " (5, True),\n", " (6, False),\n", " (7, True),\n", " (8, False),\n", " (9, False),\n", " (10, False),\n", " (11, True),\n", " (12, False),\n", " (13, True),\n", " (14, False)]" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[(x, is_prime(x)) for x in range(15)]" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[2, 3, 5, 7, 11, 13]" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[x for x in range(15) if is_prime(x)]" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ " at 0x7f73f012f168>" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Если вместо квадратных скобок поставить круглые,\n", "# то получится так называемый \"генератор\".\n", "# Он не вычисляет все элементы сразу, а умеет выдавать их по очереди\n", "# (например, в цикле)\n", "(x for x in range(15) if is_prime(x))" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[2, 3, 5, 7, 11, 13]" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list((x for x in range(15) if is_prime(x)))" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "3\n", "5\n", "7\n", "11\n", "13\n" ] } ], "source": [ "primes = (x for x in range(15) if is_prime(x))\n", "for i in primes:\n", " print(i)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Мы уже проитерировались по генератору primes, поэтому теперь он пуст\n", "# Про генераторы поговорим подробнее в следующий раз\n", "list(primes)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "{0: False,\n", " 1: False,\n", " 2: True,\n", " 3: True,\n", " 4: False,\n", " 5: True,\n", " 6: False,\n", " 7: True,\n", " 8: False,\n", " 9: False,\n", " 10: False,\n", " 11: True,\n", " 12: False,\n", " 13: True,\n", " 14: False}" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Можно еще писать выражения с фигурными скобками\n", "# Получится словарь\n", "{x: is_prime(x) for x in range(15)}" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "{3: True, 5: True, 7: True, 9: False, 11: True, 13: True, 15: False, 17: True}" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Словарь из предыдущего примера не очень интересен,\n", "# так как ключи в нем - подряд идущие неотрицательные целые числа\n", "# Вместо словаря там можно было бы использовать список\n", "# Сделаем что-нибудь поинтереснее:\n", "{x: is_prime(x) for x in range(2, 19) if x % 2 == 1}" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Как задать двумерный массив (матрицу)?\n", "# Воспользуемся для этого списком списков,\n", "# задавая матрицу как список строк\n", "A = [\n", " [1, 2, 3],\n", " [4, 5, 6],\n", " [7, 8, 9],\n", "]" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1, 2, 3], [4, 5, 6], [7, 8, 9]]\n" ] } ], "source": [ "# Обычный вывод на экран печатает все \"плоско\":\n", "print(A)" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Напишем для удобства функцию печати матрицы:\n", "def print_matrix(A):\n", " for row in A:\n", " print(row)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3]\n", "[4, 5, 6]\n", "[7, 8, 9]\n" ] } ], "source": [ "print_matrix(A)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3]\n", "[4, -153, 6]\n", "[7, 8, 9]\n" ] } ], "source": [ "# Правда, если число цифр в элементах разное, то вывод \"поплывет\":\n", "A[1][1] = -153\n", "print_matrix(A)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Напишите сами функцию, печатающую матрицу аккуратно" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 7]\n", "[2, -153, 8]\n", "[3, 6, 9]\n" ] } ], "source": [ "# Предположим, нам надо транспонировать матрицу.\n", "# Первый способ:\n", "def transpose(A):\n", " A_transp = []\n", " for j in range(len(A[0])): # число столбцов\n", " row_transp = []\n", " for row in A:\n", " row_transp.append(row[j])\n", " A_transp.append(row_transp)\n", " return A_transp\n", "\n", "print_matrix(transpose(A))" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 7]\n", "[2, -153, 8]\n", "[3, 6, 9]\n" ] } ], "source": [ "# Второй способ - то же самое, но с помощью списковых выражений\n", "def transpose2(A):\n", " return [[row[j] for row in A] for j in range(len(A[0]))]\n", "\n", "print_matrix(transpose2(A))" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1, 4, 7)\n", "(2, -153, 8)\n", "(3, 6, 9)\n" ] } ], "source": [ "# Этого же можно добиться с помощью встроенной функции zip:\n", "print_matrix(list(zip(*A)))" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[(1, 'a', 5), (2, 'b', 6), (3, 'c', 7)]" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Функция zip получает на вход несколько коллекций\n", "# и группирует их первые элементы, вторые элементы, и т. д.\n", "list(zip([1,2,3], \"abc\", [5,6,7,8]))" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Конструкция *A в zip(*A) - это способ передать элементы списка A как отдельные параметры" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Давайте научимся писать функции с переменным числом аргументов (как в zip)\n", "def f(a, b, *c, **d):\n", " print(a) # a и b - обычные обязательные аргументы\n", " print(b)\n", " print(c) # с - это кортеж (быть может пустой) из дополнительных аргументов\n", " print(d) # d - это словарь остальных именованных аргументов" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "()\n", "{}\n" ] } ], "source": [ "f(1, 2)" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "(3, 4, 5)\n", "{}\n" ] } ], "source": [ "f(1, 2, 3, 4, 5)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "(3, 4, 5)\n", "{'x': 6, 'y': 7}\n" ] } ], "source": [ "f(1, 2, 3, 4, 5, x=6, y=7)" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "(3, 4, 5)\n", "{'x': 6, 'y': 7}\n" ] } ], "source": [ "# Если у нас уже есть список или словарь (с текстовыми ключами),\n", "# то их можно \"развернуть\" и передать каждый их элемент как свой аргумент в функцию\n", "l = [3, 4, 5]\n", "d = {\"x\": 6, \"y\": 7}\n", "f(1, 2, *l, **d)" ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "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.4.3" } }, "nbformat": 4, "nbformat_minor": 0 }