{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Работа со списками" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Перебор всего списка" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Типичная задача из области программирования — перебрать все элементы списка и выполнить с каждым элементом одну и ту же операцию. Например, в компьютерной игре все экранные объекты могут смещаться на одинаковую величину, или в списке чисел к каждому элементу может применяться одна и та же статистическая операция. А может быть, вам нужно вывести все заголовки из списка статей на сайте. В ситуациях, требующих применения одного действия к каждому элементу списка, можно воспользоваться циклами for." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Допустим, имеется список с именами фокусников, и вы хотите вывести каждое имя из списка. Конечно, можно обратиться к каждому элементу по отдельности, но такой подход создает ряд проблем. Во-первых, для очень длинных списков все сведется к однообразным повторениям. Во-вторых, при любом изменении длины списка в программу придется вносить изменения. Цикл for решает обе проблемы: Python будет следить за всеми техническими деталями в своей внутренней реализации." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "alice\n", "david\n", "carolina\n" ] } ], "source": [ "magicians = ['alice', 'david', 'carolina']\n", "for car in magicians:\n", " print(car)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Более сложные действия в циклах for" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В цикле for с каждым элементом списка может выполняться практически любое действие. Дополним предыдущий пример, чтобы программа выводила для каждого фокусника отдельное сообщение:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Alice, that was a great trick!\n", "David, that was a great trick!\n", "Carolina, that was a great trick!\n" ] } ], "source": [ "magicians = ['alice', 'david', 'carolina']\n", "for magician in magicians:\n", " print(magician.title() + \", that was a great trick!\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Alice, that was a great trick!\n", "I can't wait to see your next trick, Alice.\n", "\n", "David, that was a great trick!\n", "I can't wait to see your next trick, David.\n", "\n", "Carolina, that was a great trick!\n", "I can't wait to see your next trick, Carolina.\n", "\n" ] } ], "source": [ "magicians = ['alice', 'david', 'carolina']\n", "for magician in magicians:\n", " print(magician.title() + \", that was a great trick!\")\n", " print(\"I can't wait to see your next trick, \" + magician.title() + \".\\n\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Тело цикла for может содержать сколько угодно строк кода. На практике часто требуется выполнить в цикле for несколько разных операций для каждого элемента списка." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Выполнение действий после цикла for" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Что происходит после завершения цикла for? Обычно программа выводит сводную информацию или переходит к другим операциям. Каждая строка кода после цикла for, не имеющая отступа, выполняется без повторения. Допустим, вы хотите вывести сообщение для всей группы фокусников и поблагодарить их за превосходное представление. Чтобы вывести общее сообщение после всех отдельных сообщений, разместите его после цикла for без отступа:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Alice, that was a great trick!\n", "I can't wait to see your next trick, Alice\n", "David, that was a great trick!\n", "I can't wait to see your next trick, David\n", "Carolina, that was a great trick!\n", "I can't wait to see your next trick, Carolina\n", "Thank you, everyone. That was a great magic show!\n" ] } ], "source": [ "magicians = ['alice', 'david', 'carolina']\n", "for magician in magicians:\n", " print(magician.title() + \", that was a great trick!\")\n", " print(\"I can't wait to see your next trick, \" + magician.title())\n", "print(\"Thank you, everyone. That was a great magic show!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Предотвращение ошибок сотступами" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В Python связь одной строки кода с предшествующей строкой обозначается отступами. В приведенных примерах строки, выводившие сообщения для отдельных фокусников, были частью цикла, потому что они были снабжены отступами. Применение отступов в Python сильно упрощает чтение кода. Фактически отступы заставляют разработчика писать аккуратно отформатированный код с четкой визуальной структурой. В более длинных программах Python могут встречаться блоки кода сотступами нескольких разных уровней. Эти уровни способствуют пониманию общей структуры программы. Когда разработчики только начинают писать код, работа которого зависит от правильности отступов, в их коде нередко встречаются распространенные ошибки. Например, иногда они расставляют отступы в коде, в котором эти отступыне нужны, или наоборот — забывают ставить отступы в блоках, где это необходимо.Несколько примеров помогут вам избежать подобных ошибок в будущем и успешно исправлять их, когда они встретятся в ваших программах. Итак, рассмотрим несколько типичных ошибок при использовании отступов." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Пропущенный отступ" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Строка после команды for в цикле всегда должна снабжаться отступом." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "ename": "IndentationError", "evalue": "expected an indented block (, line 3)", "output_type": "error", "traceback": [ "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m3\u001b[0m\n\u001b[1;33m print(magician)\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mIndentationError\u001b[0m\u001b[1;31m:\u001b[0m expected an indented block\n" ] } ], "source": [ "magicians = ['alice', 'david', 'carolina']for magician in magicians:print(magician)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Пропущенные отступы в других строках" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Иногда цикл выполняется без ошибок, но не выдает ожидаемых результатов. Такое часто происходит, когда вы пытаетесь выполнить несколько операций в цикле,но забываете снабдить отступом некоторые из строк. Например, вот что происходит, если вы забудете снабдить отступом вторую строку в цикле:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "ename": "IndentationError", "evalue": "unexpected indent (, line 4)", "output_type": "error", "traceback": [ "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m4\u001b[0m\n\u001b[1;33m print(\"I can't wait to see your next trick, \" + magician.title() +\".\\n\")\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mIndentationError\u001b[0m\u001b[1;31m:\u001b[0m unexpected indent\n" ] } ], "source": [ "magicians = ['alice', 'david', 'carolina']\n", "for magician in magicians:\n", " print(magician.title() + \", that was a great trick!\")\n", " print(\"I can't wait to see your next trick, \" + magician.title() +\".\\n\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Лишние отступы" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "ename": "IndentationError", "evalue": "unexpected indent (, line 2)", "output_type": "error", "traceback": [ "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m print(message)\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mIndentationError\u001b[0m\u001b[1;31m:\u001b[0m unexpected indent\n" ] } ], "source": [ "message = \"Hello Python world!\"\n", " print(message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Лишние отступы после цикла" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Alice, that was a great trick!\n", "I can't wait to see your next trick, Alice.\n", "\n", "Thank you everyone, that was a great magic show!\n", "David, that was a great trick!\n", "I can't wait to see your next trick, David.\n", "\n", "Thank you everyone, that was a great magic show!\n", "Carolina, that was a great trick!\n", "I can't wait to see your next trick, Carolina.\n", "\n", "Thank you everyone, that was a great magic show!\n" ] } ], "source": [ "magicians = ['alice', 'david', 'carolina']\n", "for magician in magicians:\n", " print(magician.title() + \", that was a great trick!\")\n", " print(\"I can't wait to see your next trick, \" + magician.title() + \".\\n\")\n", " print(\"Thank you everyone, that was a great magic show!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Пропущенное двоеточие" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Двоеточие в конце команды for сообщает Python, что следующая строка является началом цикла." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "ename": "SyntaxError", "evalue": "invalid syntax (, line 2)", "output_type": "error", "traceback": [ "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m for magician in magicians\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" ] } ], "source": [ "magicians = ['alice', 'david', 'carolina']\n", "for magician in magicians\n", " print(magician)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Создание числовых списков" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Функция range()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Функция **range()** упрощает построение числовых последовательностей. Например, с ее помощью можно легко вывести серию чисел:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n", "4\n", "5\n" ] } ], "source": [ "for value in range(1,6):\n", " print(value)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Использование range() для создания числового списка" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если вы хотите создать числовой список, преобразуйте результаты range() в список при помощи функции list(). Если заключить вызов range() в list(), то результат будет представлять собой список с числовыми элементами. В примере из предыдущего раздела числовая последовательность просто выводилась на экран. Тот же набор чисел можно преобразовать всписок вызовом list():" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3, 4, 5]\n" ] } ], "source": [ "numbers = list(range(1,6))\n", "print(numbers)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Функция range()также может генерировать числовые последовательности, пропуская числа в заданном диапазоне. Например, построение списка четных чисел от 1 до 10 происходит так:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2, 4, 6, 8, 10]\n" ] } ], "source": [ "even_numbers = list(range(2,11,2))\n", "print(even_numbers)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В этом примере функция range()начинает со значения 2, а затем увеличивает его на 2. Приращение 2 последовательно применяется до тех пор, пока небудет достигнуто или пройдено конечное значение 11, после чего выводится результат:\n", "*[2, 4, 6, 8, 10]*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "С помощью функции range() можно создать практически любой диапазон чисел. Например, как бы вы создали список квадратов всех целых чисел от 1 до 10? В языке Python операция возведения встепень обозначается двумя звездочками. Один из возможных вариантов выглядит так:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n" ] } ], "source": [ "squares = []\n", "for value in range(1,11):\n", " square = value**2\n", " squares.append(square)\n", "print(squares)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Простая статистика счисловыми списками" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n", "min(digits)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "9" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "max(digits)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "45" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(digits)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Генераторы списков" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Описанный выше способ генерирования списка squares состоял из трех или четырех строк кода. Генератор списка (list comprehension) позволяет сгенерировать тот же список всего водной строке. Генератор списка объединяет цикл for и создание новых элементов в одну строку иавтоматически присоединяет к списку все новые элементы." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В следующем примере список квадратов, знакомый вам по предыдущим примерам, строится с использованием генератора списка:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n" ] } ], "source": [ "squares = [value**2 for value in range(1,11)]\n", "print(squares)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Чтобы использовать этот синтаксис, начните ссодержательного имени списка,напримерsquares. Затем откройте квадратные скобки иопределите выражениедля значений, которые должны быть сохранены вновом списке. Вданном примере это выражение value2, которое возводит значение во вторую степень. Затем напишите цикл for для генерирования чисел, которые должны передаваться выражению, и закройте квадратные скобки. Цикл for в данном примере — for valuein range(1,11) — передает значения с 1 до 10 выражению value2. Обратите внимание на отсутствие двоеточия вконце команды for." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Работа счастью списка" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Создание среза" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Чтобы создать срез списка, следует задать индексы первого и последнего элементов,скоторыми вы намереваетесь работать. Как и в случае с функцией range(), Python останавливается на элементе, предшествующем второму индексу. Скажем, чтобы вывести первые три элемента списка, запросите индексы с 0 по 3, и вы получит еэлементы 0, 1 и 2." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['charles', 'martina', 'michael', 'florence', 'eli']\n" ] } ], "source": [ "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n", "print(players[1:5])" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['martina', 'michael', 'florence']\n" ] } ], "source": [ "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n", "print(players[1:4])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если первый индекс среза не указан, то Python автоматически начинает срез отначала списка:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['charles', 'martina', 'michael', 'florence']\n" ] } ], "source": [ "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n", "print(players[:4])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Аналогичный синтаксис работает и для срезов, включающих конец списка. Например, если вам нужны все элементы с третьего до последнего, начните синдекса 2 и не указывайте второй индекс:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['michael', 'florence', 'eli']\n" ] } ], "source": [ "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n", "print(players[2:])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Вспомните, что отрицательный индекс возвращает элемент, находящийся на заданном расстоянии от конца списка; следовательно, вы можете получить любой срез от конца списка. Например, чтобы отобрать последних трех игроков, используйте срез players[-3:]:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['michael', 'florence', 'eli']\n", "['michael', 'florence', 'eli']\n", "['michael', 'florence', 'eli']\n" ] } ], "source": [ "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n", "print(players[-3:])\n", "print (players[2:])\n", "print (players[2:5])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Перебор содержимого среза" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если вы хотите перебрать элементы, входящие в подмножество элементов, используйте срез в цикле for. В следующем примере программа перебирает первых трех игроков и выводит их имена:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Here are the first three players on my team:\n", "Charles\n", "Martina\n", "Michael\n", "Florence\n" ] } ], "source": [ "players = ['charles', 'martina', 'michael', 'florence', 'eli']\n", "print(\"Here are the first three players on my team:\")\n", "for player in players[:4]:\n", " print(player.title())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Срезы приносят огромную пользу во многих ситуациях. Например, при создании компьютерной игры итоговый счет игрока может добавляться в список после окончания текущей партии. После этого программа может получить три лучших результата игрока, отсортировав список по уменьшению и получив срез, включающий только три элемента. При работе с данными срезы могут использоваться для обработки данных блоками заданного размера. Или при построении веб-приложения срезы могут использоваться для постраничного вывода информации так, чтобы на каждой странице выводился соответствующий объем информации." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Копирование списка" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Часто разработчик берет существующий список исоздает на его основе совершенноновый. Посмотрим, как работает копирование списков, и рассмотрим одну ситуацию, в которой копирование списка может принести пользу.\n", "Чтобы скопировать список, создайте срез, включающий весь исходный список без указания первого и второго индекса ([:]). Эта конструкция создает срез, который начинается с первого элемента и завершается последним; в результате создается копия всего списка. Представьте, что вы создали список своих любимых блюд и теперь хотите создать отдельный список блюд, которые нравятся вашему другу. Пока вашему другу нравятся все блюда из нашего списка, поэтому вы можете создать другой список простым копированием нашего:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "My favorite foods are:\n", "['pizza', 'falafel', 'carrot cake']\n", "\n", "My friend's favorite foods are:\n", "['pizza', 'falafel']\n" ] } ], "source": [ "my_foods = ['pizza', 'falafel', 'carrot cake']\n", "friend_foods = my_foods[0:2]\n", "print(\"My favorite foods are:\")\n", "print(my_foods)\n", "print(\"\\nMy friend's favorite foods are:\")\n", "print(friend_foods)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "My favorite foods are:\n", "['pizza', 'falafel', 'carrot cake', 'cannoli']\n", "\n", "My friend's favorite foods are:\n", "['pizza', 'falafel', 'carrot cake', 'ice cream']\n" ] } ], "source": [ "my_foods = ['pizza', 'falafel', 'carrot cake']\n", "friend_foods = my_foods[:]\n", "my_foods.append('cannoli')\n", "friend_foods.append('ice cream')\n", "print(\"My favorite foods are:\")\n", "print(my_foods)\n", "print(\"\\nMy friend's favorite foods are:\")\n", "print(friend_foods)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Кортежи" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Списки хорошо подходят для хранения наборов элементов, которые могут изменяться на протяжении жизненного цикла программы. Например, возможность модификации списков жизненно необходима при работе со списками пользователей сайта или списками персонажей игры. Однако в некоторых ситуациях требуется создать список элементов, который не может изменяться. *Кортежи(tuples)* предоставляют именно такую возможность. В языке Python значения, которые не могут изменяться, называются неизменяемыми(immutable), а не изменяемый список называется **кортежем**." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Определение кортежа" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Кортеж выглядит как список, не считая того, что вместо квадратных скобок используются круглые скобки. После определения кортежа вы можете обращаться кего отдельным элементам по индексам точно так же, как это делается при работе со списком." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "200\n", "50\n", "bmw\n", "audi\n", "['bmw', 'mersedes']\n" ] }, { "ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[0mcars\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"mersedes\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 8\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcars\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 9\u001b[1;33m \u001b[0mdimensions\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m300\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 10\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdimensions\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" ] } ], "source": [ "dimensions = (200, 50)\n", "cars = [\"bmw\", \"audi\"]\n", "print(dimensions[0])\n", "print(dimensions[1])\n", "print(cars[0])\n", "print(cars[1])\n", "cars[1]=\"mersedes\"\n", "print(cars)\n", "dimensions[0]=300\n", "print(dimensions)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Посмотрим, что произойдет при попытке изменения одного из элементов в кортеже dimensions:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mdimensions\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m200\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m50\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mdimensions\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m250\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" ] } ], "source": [ "dimensions = (200, 50)\n", "dimensions[0] = 250" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Перебор всех значений в кортеже" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для перебора всех значений в кортеже используется цикл for, как и при работе со списками:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "200\n", "50\n" ] } ], "source": [ "dimensions = (200, 50)\n", "for dimension in dimensions:\n", " print(dimension)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Замена кортежа" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Элементы кортежа не могут изменяться, но вы можете присвоить новое значение переменной, в которой хранится кортеж. Таким образом, для изменения размеров прямоугольника следует переопределить весь кортеж:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Original dimensions:\n", "200\n", "50\n", "\n", "Modified dimensions:\n", "400\n", "100\n" ] } ], "source": [ "dimensions = (200, 50)\n", "print(\"Original dimensions:\")\n", "for dimension in dimensions:\n", " print(dimension)\n", "dimensions = (400, 100)\n", "print(\"\\nModified dimensions:\")\n", "for dimension in dimensions:\n", " print(dimension)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Стиль программирования" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Итак, вы постепенно начинаете писать более длинные программы, и вам стоит познакомиться с некоторыми рекомендациями по стилевому оформлению кода. Нежалейте времени на то, чтобы ваш код читался как можно проще. Понятный код помогает следить за тем, что делает ваша программа, и упрощает изучение вашего кода другими разработчиками.\n", "Программисты Python выработали ряд соглашений по стилю, чтобы весь код имел хотя бы отдаленно похожую структуру. Научившись писать «чистый» код Python, вы сможете понять общую структуру кода Python, написанного любым другим программистом, соблюдающим те же рекомендации. Если вы рассчитываете когда-нибудь стать профессиональным программистом, привыкайте соблюдать эти рекомендации уже сейчас, чтобы выработать полезную привычку." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Рекомендации по стилю" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Когда кто-нибудь хочет внести изменения вязык Python, он пишет документ PEP (Python Enhancement Proposal). Одним из самых старых PEP является документ PEP 8 с рекомендациями по стилевому оформлению кода. PEP 8 имеет довольно большую длину, но бульшая часть документа посвящена более сложным программным структурам, нежели те, которые встречались вам до настоящего момента. Руководство по стилю Python было написано сучетом того факта, что код читаетсячаще, чем пишется. Вы пишете свой код один раз, а потом начинаете читать его, когда переходите к отладке. При расширении функциональности программы вы снова тратите время на чтение своего кода. А когда вашим кодом начинают пользоваться другие программисты, они тоже читают его. Выбирая между написанием кода, который проще пишется, и кодом, который проще читается, программисты Python почти всегда рекомендуют второй вариант.Следующие советы помогут вам с самого начала писать чистый, понятный код." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "PEP 8 рекомендует обозначать уровень отступа четырьмя пробелами. Использование четырех пробелов упрощает чтение программы и при этом оставляет достаточно места для нескольких уровней отступов вкаждой строке.В программах форматирования текста для создания отступов часто используются табуляции вместо пробелов. Такой способ хорошо работает в текстовых процессорах, но интерпретатор Python приходит взамешательство, когда табуляции смешиваются с пробелами. В каждом текстовом редакторе имеется параметр конфигурации, который заменяет нажатие клавиши табуляции заданным количеством пробелов. Конечно, клавиша табуляции удобна, но вы должны проследить за тем, чтобы редактор вставлял в документ пробелы вместо табуляций. Смешение табуляций и пробелов в файле может создать проблемы, сильно затрудняющие диагностику. Если вы думаете, что в программе табуляции смешались с пробелами, помните, что в большинстве редакторов существует возможность преобразования всех табуляций в пробелы." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Многие программисты Python рекомендуют ограничивать длину строк 80 символами. Исторически эта рекомендация появилась из-за того, что в большинстве компьютеров водной строке терминального окна помещалось всего 79 символов. В настоящее время на экранах помещаются куда более длинные строки, но для применения стандартной длины строки в 79 символов существуют и другие причины. Профессиональные программисты часто открывают на одном экране сразунесколько файлов; стандартная длина строки позволяет видеть все строки вдвухили трех файлах, открытых на экране одновременно. PEP 8 также рекомендует ограничивать комментарии 72 символами на строку, потому что некоторые служебные программы, автоматически генерирующие документацию в больших проектах, добавляют символы форматирования в начале каждой строки комментария.\n", "Рекомендации PEP 8 по выбору длины строки не являются незыблемыми, и некоторые программисты предпочитают ограничение в 99 символов. Пока вы учитесь, длина строки в коде не так важна, но учтите, что при совместной работе в группах почти всегда соблюдаются рекомендации PEP 8. В большинстве редакторов можно установить визуальный ориентир (обычно вертикальную линию на экране), показывающий, где проходит граница." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Пустые строки применяются для визуальной группировки частей программы. Используйте пустые строки для структурирования файлов, но не злоупотребляйте ими. Примеры, приведенные в книге, помогут вам выработать нужный баланс.\n", "Например, если в программе пять строк кода создают список, а затем следующие три строки что-то делают с этим списком, два фрагмента уместно разделить пустой строкой. Тем не менее между ними не стоит вставлять три или четыре пустыестроки.Пустые строки не влияют на работу кода, но отражаются на его удобочитаемости. Интерпретатор Python использует горизонтальные отступы для интерпретации смысла кода, но игнорирует вертикальные интервалы." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "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.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }