Files
python-course-ipynb/datatype.ipynb
2020-02-24 11:32:37 +03:00

1679 lines
103 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- dom:TITLE: Типы и модель данных -->\n",
"# Типы и модель данных\n",
"<!-- dom:AUTHOR: С.В. Лемешевский Email:sergey.lemeshevsky@gmail.com at Институт математики НАН Беларуси -->\n",
"<!-- Author: --> \n",
"**С.В. Лемешевский** (email: `sergey.lemeshevsky@gmail.com`), Институт математики НАН Беларуси\n",
"\n",
"Date: **Feb 24, 2020**\n",
"\n",
"<!-- Common Mako variable and functions -->\n",
"<!-- -*- coding: utf-8 -*- -->\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"Здесь разберем как Python работает с переменными и определим, какие\n",
"типы данных можно использовать в рамках этого языка. Подробно рассмотрим модель\n",
"данных Python, а также механизмы создания и изменения значения\n",
"переменных.\n",
"\n",
"# Кратко о типизации языков программирования\n",
"<div id=\"datatype:typization\"></div>\n",
"\n",
"Если достаточно формально подходить к вопросу о типизации языка Python, то\n",
"можно сказать, что он относится к языкам с неявной сильной динамической\n",
"типизацией.\n",
"\n",
"Неявная типизация означает, что при объявлении переменной вам не нужно\n",
"указывать её тип, при явной это делать необходимо. В качестве примера языков с\n",
"явной типизацией можно привести Java, C++ . Вот как будет выглядеть объявление\n",
"целочисленной переменной в Java и Python.\n",
"\n",
"* Java:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" int a = 1 ;\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* Python:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"a = 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- Local Variables: -->\n",
"<!-- doconce-chapter-nickname: \"chapter\" -->\n",
"<!-- doconce-section-nickname: \"typization\" -->\n",
"<!-- End: -->\n",
"# Типы данных в Python\n",
"<div id=\"datatype:types\"></div>\n",
"\n",
"В Python типы данных можно разделить на встроенные в интерпретатор (`built-in`) и\n",
"не встроенные, которые можно использовать при импортировании соответствующих\n",
"модулей.\n",
"\n",
"К основным встроенным типам относятся:\n",
"1. `None` (неопределенное значение переменной)\n",
"\n",
"2. Логические переменные (`Boolean Type`)\n",
"\n",
"3. Числа (`Numeric Type`)\n",
"\n",
"a. `int` целое число\n",
"\n",
"b. `float` число с плавающей точкой\n",
"\n",
"c. `complex` комплексное число\n",
"\n",
"\n",
"4. Списки (`Sequence Type`)\n",
"\n",
"a. `list` список\n",
"\n",
"b. `tuple` кортеж\n",
"\n",
"c. `range` диапазон\n",
"\n",
"\n",
"4. Строки (`Text Sequence Type`)\n",
"\n",
"a. `str`\n",
"\n",
"\n",
"2. Бинарные списки ( Binary Sequence Types )\n",
"\n",
"a. `bytes` байты\n",
"\n",
"b. `bytearray` массивы байт\n",
"\n",
"c. `memoryview` специальные объекты для доступа к внутренним данным объекта через `protocol buffer`\n",
"\n",
"\n",
"4. Множества (`Set Types`)\n",
"\n",
"a. `set` множество\n",
"\n",
"b. `frozenset` неизменяемое множество\n",
"\n",
"\n",
"3. Словари (`Mapping Types`)\n",
"\n",
"a. `dict` словарь\n",
"<!-- Local Variables: -->\n",
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
"<!-- doconce-section-nickname: \"types\" -->\n",
"<!-- End: -->\n",
"\n",
"\n",
"## Модель данных\n",
"<div id=\"datatype:model\"></div>\n",
"\n",
"Рассмотрим как создаются объекты в памяти, их устройство, процесс объявления\n",
"новых переменных и работу операции присваивания.\n",
"\n",
"Для того, чтобы объявить и сразу инициализировать переменную необходимо\n",
"написать её имя, потом поставить знак равенства и значение, с которым эта\n",
"переменная будет создана.\n",
"\n",
"Например строка:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"b = 5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Объявляет переменную `b` и присваивает ей значение `5`.\n",
"\n",
"Целочисленное значение `5` в рамках языка Python по сути своей является\n",
"*объектом*. Объект, в данном случае это абстракция для представления данных,\n",
"данные это числа, списки, строки и т.п. При этом, под *данными* следует понимать как\n",
"непосредственно сами объекты, так и отношения между ними (об этом чуть позже).\n",
"Каждый объект имеет три атрибута это *идентификатор*, *значение* и *тип*.\n",
"\n",
"*Идентификатор* это уникальный признак объекта, позволяющий отличать объекты\n",
"друг от друга, а *значение* непосредственно информация, хранящаяся в памяти,\n",
"которой управляет интерпретатор. \n",
"\n",
"При инициализации переменной, на уровне интерпретатора, происходит\n",
"следующее:\n",
"* создается целочисленный объект `5` (можно представить, что в этот момент создается ячейка и число `5` «кладется» в эту ячейку);\n",
"\n",
"* данный объект имеет некоторый идентификатор, значение: `5`, и тип: целое число;\n",
"\n",
"* посредством оператора `=` создается ссылка между переменной `b` и целочисленным объектом `5` (переменная `b` ссылается на объект `5`).\n",
"\n",
"> **Об именах переменных.**\n",
">\n",
"> Допустимые имена переменных в языке Python это последовательность\n",
"> символов произвольной длины, содержащей «начальный символ»\n",
"> и ноль или более «символов продолжения». Имя переменной должно\n",
"> следовать определенным правилам и соглашениям. \n",
"> \n",
"> Первое правило касается начального символа и символов\n",
"> продолжения. Начальным символом может быть любой символ, который в\n",
"> кодировке Юникод рассматривается как принадлежащий диапазону\n",
"> алфавитных символов ASCII (`a`, `b`, ..., `z`, `A`, `B`, ..., `Z`),\n",
"> символ подчеркивания (`_`), а также символы большинства национальных\n",
"> (не английских) алфавитов. Каждый символ продолжения может быть\n",
"> любым символом из тех, что пригодны в качестве начального символа,\n",
"> а также любым непробельным символом, включая символы, которые\n",
"> в кодировке Юникод считаются цифрами, такие как (`0`, `1`, ...,\n",
"> `9`), и символ Каталана `·`. Идентификаторы чувствительны к регистру,\n",
"> поэтому `TAXRATE`, `Taxrate`, `TaxRate`, `taxRate` и `taxrate` это\n",
"> пять разных переменных. \n",
"> \n",
"> Имя переменной не должно совпадать с ключевыми словами интерпретатора\n",
"> Python. Список ключевых слов можно получить непосредственно в программе, для\n",
"> этого нужно подключить модуль `keyword` и воспользоваться командой\n",
"> `keyword.kwlist`."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import keyword\n",
"print(\"Python keywords: \" , keyword.kwlist)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> \n",
"> Проверить является или нет идентификатор ключевым словом можно так:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"keyword.iskeyword( \"try\" )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
">"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"keyword.iskeyword( \"b\" )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Об использовании символа подчеркивания в именах переменных.**\n",
">\n",
"> Не должны использоваться имена, начинающиеся и заканчивающиеся двумя\n",
"> символами подчеркивания (такие как `__lt__`). В языке \n",
"> Python определено множество различных специальных методов и переменных\n",
"> с такими именами (и в случае специальных методов мы можем заменять их,\n",
"> то есть создать свои версии этих методов), но мы не должны вводить\n",
"> новые имена такого рода.\n",
"> \n",
"> Символ подчеркивания сам по себе может использоваться в качестве\n",
"> идентификатора; внутри интерактивной оболочки интерпретатора или\n",
"> в командной оболочке Python в переменной с именем `_` сохраняется\n",
"> результат последнего вычисленного выражения. Во время выполнения\n",
"> обычной программы идентификатор `_` отсутствует, если мы явно не\n",
"> определяем его в своем программном коде. Некоторые программисты \n",
"> любят использовать `_` в качестве идентификатора переменной цикла\n",
"> в циклах `for` ... `in`, когда не требуется обращаться к элементам, по\n",
"> которым выполняются итерации. Например:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"for _ in (0, 1, 2, 3, 4, 5):\n",
" print(\"Hello\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Для того, чтобы посмотреть на объект с каким идентификатором ссылается данная\n",
"переменная, можно использовать функцию `id()`."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"a = 4\n",
"b = 5\n",
"id (a)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"id (b)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"a = b\n",
"id (a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Как видно из примера, идентификатор это некоторое целочисленное значение,\n",
"посредством которого уникально адресуется объект. Изначально переменная a\n",
"ссылается на объект `4` с идентификатором `1829984576`, переменная `b`\n",
" на объект с `id = 1829984592`. После выполнения операции\n",
"присваивания `a = b`, переменная a стала ссылаться на тот же объект,\n",
"что и `b`.\n",
"\n",
"<!-- dom:FIGURE: [fig-datatype/refs.png, width=600 frac=1.0] -->\n",
"<!-- begin figure -->\n",
"![](fig-datatype/refs.png)<!-- end figure -->\n",
"\n",
"\n",
"Тип переменной можно определить с помощью функции `type()`. Пример\n",
"использования приведен ниже."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"a = 10\n",
"b = \"hello\"\n",
"c = ( 1 , 2 )\n",
"type (a)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"type (b)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"type (c)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- Local Variables: -->\n",
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
"<!-- doconce-section-nickname: \"model\" -->\n",
"<!-- End: -->\n",
"# Изменяемые и неизменяемые типы данных\n",
"<div id=\"datatype:mutable\"></div>\n",
"\n",
"В Python существуют изменяемые и неизменяемые типы.\n",
"\n",
"К неизменяемым (`immutable`) типам относятся:\n",
"* целые числа (`int`);\n",
"\n",
"* числа с плавающей точкой (`float`);\n",
"\n",
"* комплексные числа (`complex`);\n",
"\n",
"* логические переменные (`bool`);\n",
"\n",
"* кортежи (`tuple`);\n",
"\n",
"* строки (`str`);\n",
"\n",
"* неизменяемые множества (`frozen set`).\n",
"\n",
"К изменяемым ( mutable ) типам относятся\n",
"* списки (`list`);\n",
"\n",
"* множества (`set`);\n",
"\n",
"* словари (`dict`).\n",
"\n",
"Как уже было сказано ранее, при создании переменной, вначале создается объект,\n",
"который имеет уникальный идентификатор, тип и значение, после этого переменная\n",
"может ссылаться на созданный объект.\n",
"\n",
"Неизменяемость типа данных означает, что созданный объект больше не\n",
"изменяется. Например, если мы объявим переменную `k = 15`, то будет создан объект\n",
"со значением `15`, типа `int` и идентификатором, который можно узнать с помощью\n",
"функции `id()`."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"k = 15\n",
"id (k)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"type (k)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Объект с `id = 1672501744` будет иметь значение `15` и изменить его уже нельзя.\n",
"Если тип данных изменяемый, то можно менять значение объекта.\n",
"\n",
"Например, создадим список `[1, 2]`, а потом заменим второй элемент на\n",
"`3`."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"a = [1 ,2]\n",
"id (a)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"a[1] = 3\n",
"a"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"id(a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Как видно, объект на который ссылается переменная `a`, был изменен. Это можно\n",
"проиллюстрировать следующим рисунком.\n",
"\n",
"<!-- dom:FIGURE: [fig-datatype/mute.png, width=600 frac=1.0] -->\n",
"<!-- begin figure -->\n",
"![](fig-datatype/mute.png)<!-- end figure -->\n",
"\n",
"\n",
"В рассмотренном случае, в качестве данных списка, выступают не объекты, а\n",
"отношения между объектами. Т.е. в переменной a хранятся ссылки на объекты\n",
"содержащие числа `1` и `3`, а не непосредственно сами эти числа.\n",
"\n",
"<!-- Local Variables: -->\n",
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
"<!-- doconce-section-nickname: \"mutable\" -->\n",
"<!-- End: -->\n",
"# Целочисленные типы\n",
"<div id=\"datatype:decimal\"></div>\n",
"\n",
"В языке Python имеется два целочисленных типа, `int` и `bool`. И целые\n",
"числа, и логические значения являются неизменяемыми объектами,\n",
"но благодаря присутствию в языке Python комбинированных операторов\n",
"присваивания эта особенность практически незаметна. В логических\n",
"выражениях число `0` и значение `False` представляют `False`, а любое\n",
"другое целое число и значение `True` представляют `True`. В числовых \n",
"выражениях значение `True` представляет `1`, а `False` `0`. Это означает,\n",
"что можно записывать весьма странные выражения, например, выражение `i\n",
"+= True` увеличит значение `i` на единицу. Естественно, более\n",
"правильным будет записывать подобные выражения как `i += 1`. \n",
"\n",
"Размер целого числа ограничивается только объемом памяти компьютера,\n",
"поэтому легко можно создать и обрабатывать целое число, состоящее из\n",
"тысяч цифр, правда, скорость работы с такими числами существенно\n",
"медленнее, чем с числами, которые соответствуют машинному\n",
"представлению.\n",
"\n",
"Литералы целых чисел по умолчанию записываются в десятичной сис-\n",
"теме счисления, но при желании можно использовать другие системы\n",
"счисления:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"14600926"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"0b110111101100101011011110"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"0o67545336"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"0xDECADE"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Двоичные числа записываются с префиксом `0b`, восьмеричные в\n",
"префиксом `0o` и шестнадцатеричные с префиксом `0x`. В префиксах\n",
"допускается использовать символы верхнего регистра.\n",
"\n",
"При работе с целыми числами могут использоваться обычные\n",
"математические функции и операторы, как показано в\n",
"табл. [Таблица 1 : Арифметические операторы и функции](#datatype:tbl:1). Для арифметических операций `+`, `-`, `/`,\n",
"`//`, `%` и `**` имеются соответствующие комбинированные операторы\n",
"присваивания: `+=`, `-=`, `/=`, `//=`, `%=` и `**=`, где выражение\n",
"`x op= y` является эквивалентом выражения `x = x op y`.\n",
"\n",
"\n",
"## Таблица 1 : Арифметические операторы и функции\n",
"<div id=\"datatype:tbl:1\"></div>\n",
"\n",
"\n",
"<table border=\"1\">\n",
"<thead>\n",
"<tr><th align=\"left\"> Синтаксис </th> <th align=\"left\"> Описание </th> </tr>\n",
"</thead>\n",
"<tbody>\n",
"<tr><td align=\"left\"> <code>x + y</code> </td> <td align=\"left\"> Складывает число <code>x</code> и число <code>y</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>x - y</code> </td> <td align=\"left\"> Вычитает число <code>y</code> из числа <code>x</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>x * y</code> </td> <td align=\"left\"> Умножает <code>x</code> на <code>y</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>x / y</code> </td> <td align=\"left\"> Делит <code>x</code> на <code>y</code> результатом всегда является значение типа <code>float</code> (или <code>complex</code>, если <code>x</code> или <code>y</code> является комплексным числом) </td> </tr>\n",
"<tr><td align=\"left\"> <code>x // y</code> </td> <td align=\"left\"> Делит <code>x</code> на <code>y</code>, при этом усекает дробную часть, поэтому результатом всегда является значение типа <code>int</code>; смотрите также функцию <code>round()</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>x % y</code> </td> <td align=\"left\"> Возвращает модуль (остаток) от деления <code>x</code> на <code>y</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>x**y</code> </td> <td align=\"left\"> Возводит <code>x</code> в степень <code>y</code>; смотрите также функцию <code>pow()</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>-x</code> </td> <td align=\"left\"> Изменяет знак числа <code>x</code>, если оно не является нулем, если ноль ничего не происходит </td> </tr>\n",
"<tr><td align=\"left\"> <code>+x</code> </td> <td align=\"left\"> Ничего не делает иногда используется для повышения удобочитаемости программного кода </td> </tr>\n",
"<tr><td align=\"left\"> <code>abs(x)</code> </td> <td align=\"left\"> Возвращает абсолютное значение <code>x</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>divmod(x, y)</code> </td> <td align=\"left\"> Возвращает частное и остаток деления <code>x</code> на <code>y</code> в виде кортежа двух значений типа <code>int</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>pow(x, y)</code> </td> <td align=\"left\"> Возводит <code>x</code> в степень <code>y</code>; то же самое что и оператор <code>**</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>pow(x, y, z)</code> </td> <td align=\"left\"> Более быстрая альтернатива выражению <code>(x ** y) % z</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>round(x, n)</code> </td> <td align=\"left\"> Возвращает значение типа <code>int</code>, соответствующее значению <code>x</code> типа <code>float</code>, округленному до ближайшего целого числа (или значение типа <code>float</code>, округленное до $n$-го знака после запятой, если задан аргумент <code>n</code>) </td> </tr>\n",
"</tbody>\n",
"</table>\n",
"\n",
"\n",
"Объекты могут создаваться путем присваивания литералов переменным,\n",
"например, `x = 17`, или обращением к имени соответствующего типа как к\n",
"функции, например, `x = int(17)`. Создание объекта посредством\n",
"использования его типа может быть выполнено одним из трех способов:\n",
"\n",
"* вызов типа данных без аргументов. В этом случае объект приобретает значение по умолчанию, например, выражение `x = int()` создаст целое число `0`. Любые встроенные типы могут вызываться без аргументов.\n",
"\n",
"* тип вызывается с единственным аргументом. Если указан аргумент соответствующего типа, будет создана поверхностная копия оригинального объекта. Если задан аргумент другого типа, будет предпринята попытка выполнить преобразование. Такой способ использования описывается в табл. [datatype:tbl:2](#datatype:tbl:2)\n",
"\n",
"* передается два или более аргументов; не все типы поддерживают такую возможность, а для тех типов, что поддерживают ее, типы аргументов и их назначение отличаются. В случае типа `int` допускается передавать два аргумента, где первый аргумент это строка с представлением целого числа, а второй аргумент число основания системы счисления. Например, вызов `int(\"A4\", 16)` создаст десятичное значение `164`.\n",
"\n",
"## Таблица 2 : Функции преобразования целых чисел <div id=\"datatype:tbl:2\"></div>\n",
"\n",
"\n",
"<table border=\"1\">\n",
"<thead>\n",
"<tr><th align=\"left\"> Синтаксис </th> <th align=\"left\"> Описание </th> </tr>\n",
"</thead>\n",
"<tbody>\n",
"<tr><td align=\"left\"> <code>bin(i)</code> </td> <td align=\"left\"> Возвращает двоичное представление целого числа <code>i</code> в виде строки, например, <code>bin(1980) == '0b11110111100'</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>hex(i)</code> </td> <td align=\"left\"> Возвращает шестнадцатеричное представление целого числа <code>i</code> в виде строки, например, <code>hex(1980) == '0x7bc'</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>int(x)</code> </td> <td align=\"left\"> Преобразует объект <code>x</code> в целое число; в случае ошибки во время преобразования возбуждает исключение <code>ValueError</code>, а если тип объекта <code>x</code> не поддерживает преобразование в целое число возбуждает исключение <code>TypeError</code>. Если <code>x</code> является числом с плавающей точкой, оно преобразуется в целое число путем усечения дробной части. </td> </tr>\n",
"<tr><td align=\"left\"> <code>int(s, base)</code> </td> <td align=\"left\"> Преобразует строку <code>s</code> в целое число; в случае ошибки возбуждает исключение <code>ValueError</code>. Если задан необязательный аргумент <code>base</code>, он должен быть целым числом в диапазоне от <code>2</code> до <code>36</code> включительно. </td> </tr>\n",
"<tr><td align=\"left\"> <code>oct(i)</code> </td> <td align=\"left\"> Возвращает восьмеричное представление целого числа <code>i</code> в виде строки, например, <code>oct(1980) == '0o3674'</code> </td> </tr>\n",
"</tbody>\n",
"</table>\n",
"\n",
"\n",
"В табл. [datatype:tbl:3](#datatype:tbl:3) перечислены битовые операторы. Все битовые операторы\n",
"(`|`, `^`, `&`, `<<` и `>>`) имеют соответствующие комбинированные операторы\n",
"присваивания (`|=`, `^=`, `&=`, `<<=` и `>>=`), где выражение `i op= j` является\n",
"логическим эквивалентом выражения `i = i op j` в случае, когда обращение\n",
"к значению `i` не имеет побочных эффектов. \n",
"\n",
"\n",
"## Таблица 3 : Функции преобразования целых чисел <div id=\"datatype:tbl:3\"></div>\n",
"\n",
"\n",
"<table border=\"1\">\n",
"<thead>\n",
"<tr><th align=\"left\">Синтаксис</th> <th align=\"left\"> Описание </th> </tr>\n",
"</thead>\n",
"<tbody>\n",
"<tr><td align=\"left\"> <code>i | j</code> </td> <td align=\"left\"> Битовая операция OR (ИЛИ) над целыми числами <code>i</code> и <code>j</code>; отрицательные числа представляются как двоичное дополнение </td> </tr>\n",
"<tr><td align=\"left\"> <code>i ^ j</code> </td> <td align=\"left\"> Битовая операция XOR (исключающее ИЛИ) над целыми числами <code>i</code> и <code>j</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>i & j</code> </td> <td align=\"left\"> Битовая операция AND (И) над целыми числами <code>i</code> и <code>j</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>i << j</code> </td> <td align=\"left\"> Сдвигает значение <code>i</code> влево на <code>j</code> битов аналогично операции <code>i * (2 ** j)</code> без проверки на переполнение </td> </tr>\n",
"<tr><td align=\"left\"> <code>i >> j</code> </td> <td align=\"left\"> Сдвигает значение <code>i</code> вправо на <code>j</code> битов аналогично операции <code>i // (2 ** j)</code> без проверки на переполнение </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\~i</code> </td> <td align=\"left\"> Инвертирует биты числа <code>i</code> </td> </tr>\n",
"</tbody>\n",
"</table>\n",
"\n",
"\n",
"## Логические значения\n",
"<div id=\"datatype:decimal:bool\"></div>\n",
"\n",
"Существует два встроенных логических объекта: `True` и `False`. Как\n",
"и все остальные типы данных в языке Python (встроенные, библиотечные\n",
"или ваши собственные), тип данных `bool` может вызываться как \n",
"функция при вызове без аргументов возвращается значение `False`,\n",
"при вызове с аргументом типа `bool` возвращается копия аргумента,\n",
"а при вызове с любым другим аргументом предпринимается попытка\n",
"преобразовать указанный объект в тип `bool`. Все встроенные типы\n",
"данных и типы данных из стандартной библиотеки могут быть\n",
"преобразованы в тип `bool`, а добавить поддержку такого преобразования в\n",
"свои собственные типы данных не представляет никакой сложности. Ниже\n",
"приводится пара присваиваний логических значений и пара логических\n",
"выражений:"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"t = True"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"f = False"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"t and f"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"t and True"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"в языке Python имеется три логических оператора: `and`, `or` и\n",
"`not`. Выражения с участием операторов `and` и `or` вычисляются в\n",
"соответствии с логикой сокращенных вычислений (*short-circuit logic*),\n",
"и возвращается операнд, определяющий значение всего\n",
"выражения, тогда как результатом оператора `not` всегда\n",
"является либо `True`, либо `False`.\n",
"\n",
"\n",
"<!-- Local Variables: -->\n",
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
"<!-- doconce-section-nickname: \"decimal\" -->\n",
"<!-- End: -->\n",
"# Типы чисел с плавающей точкой\n",
"<div id=\"datatype:float\"></div>\n",
"\n",
"Язык Python предоставляет три типа значений с плавающей точкой:\n",
"встроенные типы `float` и `complex` и тип `decimal.Decimal` в\n",
"стандартной библиотеке. Все три типа данных относятся к категории\n",
"неизменяемых. Тип `float` представляет числа с плавающей точкой\n",
"двойной точности, диапазон значений которых зависит от компилятора\n",
"языка C (или C\\# или Java), применявшегося для компиляции интерпретатора\n",
"Python. Числа этого типа имеют ограниченную точность и не могут\n",
"надежно сравниваться на равенство значений. Числа типа `float`\n",
"записываются с десятичной точкой или в экспоненциальной форме записи, \n",
"например, `0.0`, `4.`, `5.7`, `-2.5`, `-2e9`, `8.9e-4`.\n",
"\n",
"В машинном представлении числа с плавающей точкой хранятся как\n",
"двоичные числа. Это означает, что одни дробные значения могут быть\n",
"представлены точно (такие как `0.5`), а другие только приблизительно\n",
"(такие как `0.1` и `0.2`). Кроме того, для представления используется\n",
"фиксированное число битов, поэтому существует ограничение на\n",
"количество цифр в представлении таких чисел. Ниже приводится\n",
"поясняющий пример:"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"0.0, 5.4, -2.5, 8.9e-4"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Проблема потери точности это не проблема, свойственная только\n",
"языку Python; все языки программирования обнаруживают проблему\n",
"с точным представлением чисел с плавающей точкой.\n",
"\n",
"Если действительно необходимо обеспечить высокую точность,\n",
"можно использовать числа типа `decimal.Decimal`. Эти числа\n",
"обеспечивают уровень точности, который вы укажете (по умолчанию 28\n",
"знаков после запятой), и могут точно представлять периодические числа,\n",
"такие как $0.1$ , но скорость работы с такими числами существенно\n",
"ниже, чем с обычными числами типа `float`. Вследствие высокой точности\n",
"числа типа `decimal.Decimal` прекрасно подходят для производства\n",
"финансовых вычислений.\n",
"\n",
"Смешанная арифметика поддерживается таким образом, что результатом\n",
"выражения с участием чисел типов `int` и `float` является число типа\n",
"`float`, а с участием типов `float` и `complex` результатом является\n",
"число типа `complex`. Поскольку числа типа `decimal.Decimal` имеют\n",
"фиксированную точность, они могут участвовать в выражениях только с\n",
"другими числами `decimal.Decimal` и с числами типа `int`; результатом \n",
"таких выражений является число `decimal.Decimal`. В случае попытки\n",
"выполнить операцию над несовместимыми типами возбуждается исключение\n",
"`TypeError`.\n",
"\n",
"## Числа с плавающей точкой\n",
"<div id=\"datatype:float:foat\"></div>\n",
"\n",
"Все числовые операторы и функции, представленные в\n",
"табл. [Таблица 1 : Арифметические операторы и функции](#datatype:tbl:1), могут применяться к числам типа float,\n",
"включая комбинированные операторы присваивания. Тип данных float может\n",
"вызываться как функция без аргументов возвращается число `0.0`, с\n",
"аргументом типа float возвращается копия аргумента, а с аргументом\n",
"любого другого типа предпринимается попытка выполнить преобразование\n",
"указанного объекта в тип float. При преобразовании строки \n",
"аргумент может содержать либо простую форму записи числа с десятичной\n",
"точкой, либо экспоненциальное представление числа. При выполнении\n",
"операций с числами типа float может возникнуть ситуация, \n",
"когда в результате получается значение `NaN` (*not a number* не\n",
"число) или «бесконечность». К сожалению, поведение интерпретатора в\n",
"таких ситуациях может отличаться в разных реализациях и зависит от \n",
"математической библиотеки системы.\n",
"\n",
"Ниже приводится пример простой функции, выполняющей сравнение\n",
"чисел типа float на равенство в пределах машинной точности:"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def equal_float(a, b):\n",
" return abs(a - b) <= sys.float_info.epsilon"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Чтобы воспользоваться этой функцией, необходимо импортировать\n",
"модуль `sys`. Объект `sys.float_info` имеет множество атрибутов. Так,\n",
"`sys.float_info.epsilon` хранит минимально возможную разницу между\n",
"двумя числами с плавающей точкой. На одной из 32-разрядных машин\n",
"автора книги это число чуть больше $0.000 000 000 000 000 2$.\n",
"Тип `float` в языке Python обеспечивает надежную точность до 17\n",
"значащих цифр.\n",
"\n",
"В дополнение к встроенным функциональным возможностям работы\n",
"с числами типа `float` модуль `math` предоставляет множество функций,\n",
"которые приводятся в табл. [datatype:tbl:4](#datatype:tbl:4). Ниже приводятся\n",
"несколько фрагментов программного кода, демонстрирующих, как можно\n",
"использовать функциональные возможности модуля:"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import math\n",
"math.pi * (5 ** 2)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"math.hypot(5, 12)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"math.modf(13.732)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Модуль `math` в значительной степени опирается на математическую\n",
"библиотеку, с которой был собран интерпретатор Python. Это означает,\n",
"что при некоторых условиях и в граничных случаях функции модуля могут\n",
"иметь различное поведение на различных платформах. \n",
"\n",
"\n",
"## Таблица 4 : Функции и константы модуля `math` <div id=\"datatype:tbl:4\"></div>\n",
"\n",
"\n",
"<table border=\"1\">\n",
"<thead>\n",
"<tr><th align=\"left\"> Синтаксис </th> <th align=\"left\"> Описание </th> </tr>\n",
"</thead>\n",
"<tbody>\n",
"<tr><td align=\"left\"> <code>math.acos(x)</code> </td> <td align=\"left\"> Возвращает арккосинус <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.acosh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический арккосинус <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.asin(x)</code> </td> <td align=\"left\"> Возвращает арксинус <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.asinh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический арксинус <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.atan(x)</code> </td> <td align=\"left\"> Возвращает арктангенс <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.atan2(y x)</code> </td> <td align=\"left\"> Возвращает арктангенс <code>y/x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.atanh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический арктангенс <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.ceil(x)</code> </td> <td align=\"left\"> Возвращает $ | x | $, то есть наименьшее целое число типа <code>int</code>, большее и равное <code>x</code>, например, <code>math.ceil(5.4) == 6</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.copysign(x y)</code> </td> <td align=\"left\"> Возвращает <code>x</code> со знаком числа <code>y</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.cos(x)</code> </td> <td align=\"left\"> Возвращает косинус <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.cosh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический косинус <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.degrees(r)</code> </td> <td align=\"left\"> Преобразует число <code>r</code> типа <code>float</code> из радианов в градусы </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.e</code> </td> <td align=\"left\"> Константа $e$, примерно равная значению $2.7182818284590451$ </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.exp(x)</code> </td> <td align=\"left\"> Возвращает $e^x$, то есть <code>math.e ** x</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.fabs(x)</code> </td> <td align=\"left\"> Возвращает $ | x | $, то есть абсолютное значение <code>x</code> в виде числа типа <code>float</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.factorial(x)</code> </td> <td align=\"left\"> Возвращает $x!$ </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.floor(x)</code> </td> <td align=\"left\"> Возвращает $ | x | $, то есть наименьшее целое число типа <code>int</code>, меньшее и равное <code>x</code>, например, <code>math.floor(5.4) == 5</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.fmod(x y)</code> </td> <td align=\"left\"> Выполняет деление по модулю (возвращает остаток) числа <code>x</code> на число <code>y</code>; дает более точный результат, чем оператор <code>%</code>, применительно к числам типа <code>float</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.frexp(x)</code> </td> <td align=\"left\"> Возвращает кортеж из двух элементов с мантиссой (в виде числа типа <code>float</code>) и экспонентой (в виде числа типа <code>int</code>) </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.fsum(i)</code> </td> <td align=\"left\"> Возвращает сумму значений в итерируемом объекте <code>i</code> в виде числа типа <code>float</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.hypot(x y)</code> </td> <td align=\"left\"> Возвращает $\\sqrt{x^2 + y^2}$ </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.isinf(x)</code> </td> <td align=\"left\"> Возвращает <code>True</code>, если значение <code>x</code> типа <code>float</code> является бесконечностью ($\\pm \\infty$) </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.isnan(x)</code> </td> <td align=\"left\"> Возвращает <code>True</code>, если значение <code>x</code> типа <code>float</code> не является числом </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.ldexp(m e)</code> </td> <td align=\"left\"> Возвращает $m\\times 2^e$ операция обратная <code>math.frexp()</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.log(x b)</code> </td> <td align=\"left\"> Возвращает $\\log_b x$, аргумент <code>b</code> является необязательным и по умолчанию имеет значение <code>math.e</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.log10(x)</code> </td> <td align=\"left\"> Возвращает $log_{10} x$ </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.log1p(x)</code> </td> <td align=\"left\"> Возвращает $log_e (1+x)$; дает точные значения даже когда значение <code>x</code> близко к <code>0</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.modf(x)</code> </td> <td align=\"left\"> Возвращает дробную и целую часть числа <code>x</code> в виде двух значений типа <code>float</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.pi</code> </td> <td align=\"left\"> Константа $\\pi$, примерно равная $3.1415926535897931$ </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.pow(x y)</code> </td> <td align=\"left\"> Возвращает $x^y$ в виде числа типа <code>float</code> </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.radians(d)</code> </td> <td align=\"left\"> Преобразует число <code>d</code> типа <code>float</code> из градусов в радианы </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.sin(x)</code> </td> <td align=\"left\"> Возвращает синус <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.sinh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический синус <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.sqrt(x)</code> </td> <td align=\"left\"> Возвращает $\\sqrt{x}$ </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.tan(x)</code> </td> <td align=\"left\"> Возвращает тангенс <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.tanh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический тангенс <code>x</code> в радианах </td> </tr>\n",
"<tr><td align=\"left\"> <code>math.trunc(x)</code> </td> <td align=\"left\"> Возвращает целую часть числа <code>x</code> в виде значения типа <code>int</code>; то же самое что и <code>int(x)</code> </td> </tr>\n",
"</tbody>\n",
"</table>\n",
"\n",
"\n",
"## Комплексные числа\n",
"<div id=\"datatype:float:complex\"></div>\n",
"\n",
"Тип данных `complex` относится к категории неизменяемых и хранит пару\n",
"значений типа `float`, одно из которых представляет действительную\n",
"часть комплексного числа, а другое мнимую. Литералы комплексных\n",
"чисел записываются как действительная и мнимая части, объединенные\n",
"знаком `+` или `-`, а за мнимой частью числа следует символ `j`.\n",
"Вот примеры нескольких комплексных чисел: `3.5+2j`, `0.5j`, `4+0j`,\n",
"`-1 - 3.7j`. Обратите внимание, что если действительная часть числа\n",
"равна `0`, ее можно вообще опустить.\n",
"\n",
"Отдельные части комплексного числа доступны в виде атрибутов `real`\n",
"и `imag`. Например:"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"z = -89.5+2.125j\n",
"z.real, z.imag"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"За исключением `//`, `%`, `divmod()` и версии `pow()` с тремя\n",
"аргументами все остальные арифметические операторы и функции,\n",
"перечисленные в табл. [Таблица 1 : Арифметические операторы и функции](#datatype:tbl:1) могут использоваться для\n",
"работы с комплексными числами, так же как и соответствующие\n",
"комбинированные операторы присваивания. Кроме того, значения типа\n",
"`complex` имеют метод `conjugate()`, который изменяет знак мнимой\n",
"части. Например:"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"z.conjugate()"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"3-4j.conjugate()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Тип данных `complex` может вызываться как функция без аргументов\n",
"она вернет значение `0j`, с аргументом типа `complex` она вернет копию\n",
"аргумента, а с аргументом любого другого типа она попытается\n",
"преобразовать указанный объект в значение типа `complex`. При\n",
"использовании для преобразования функция `complex()` принимает либо\n",
"единственный строковый аргумент, либо одно или два значения типа\n",
"`float`.\n",
"\n",
"Если ей передается единственное значение типа `float`, возвращается\n",
"комплексное число с мнимой частью, равной `0j`.\n",
"\n",
"Функции в модуле `math` не работают с комплексными числами. Это\n",
"сделано преднамеренно, чтобы гарантировать, что пользователи модуля \n",
"`math` будут получать исключения вместо получения комплексных чисел в\n",
"некоторых случаях.\n",
"\n",
"Если возникает необходимость использовать комплексные числа,\n",
"можно воспользоваться модулем `cmath`, который содержит комплексные\n",
"версии большинства тригонометрических и логарифмических функций,\n",
"присутствующих в модуле math, плюс ряд функций, специально\n",
"предназначенных для работы с комплексными числами, таких \n",
"как `cmath.phase()`, `cmath.polar()` и `cmath.rect()`, а также\n",
"константы `cmath.pi` и `cmath.e`, которые хранят те же самые значения\n",
"типа `float`, что и родственные им константы в модуле `math`.\n",
"\n",
"## Числа типа `Decimal`\n",
"<div id=\"datatype:float:decimal\"></div>\n",
"\n",
"Во многих приложениях недостаток точности, свойственный числам\n",
"типа `float`, не имеет существенного значения, и эта неточность\n",
"окупается скоростью вычислений. Но в некоторых случаях предпочтение \n",
"отдается точности, даже в обмен на снижение скорости работы. Модуль\n",
"`decimal` реализует неизменяемый числовой тип `Decimal`, который\n",
"представляет числа с задаваемой точностью. Вычисления с участием \n",
"таких чисел производятся значительно медленнее, чем в случае\n",
"использования значений типа `float`, но насколько это важно, будет\n",
"зависеть от приложения.\n",
"\n",
"Чтобы создать объект типа `Decimal`, необходимо импортировать модуль\n",
"`decimal`. Например:"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import decimal\n",
"a = decimal.Decimal(9876)\n",
"b = decimal.Decimal(\"54321.012345678987654321\")\n",
"a + b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- Local Variables: -->\n",
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
"<!-- doconce-section-nickname: \"float\" -->\n",
"<!-- End: -->\n",
"# Строки\n",
"<div id=\"datatype:strings\"></div>\n",
"\n",
"Строки в языке Python представлены неизменяемым типом данных `str`,\n",
"который хранит последовательность символов Юникода. Тип данных `str`\n",
"может вызываться как функция для создания строковых объектов без\n",
"аргументов возвращается пустая строка; с аргументом, который не\n",
"является строкой, возвращается строковое представление аргумента; а в\n",
"случае, когда аргумент является строкой, возвращается его\n",
"копия. Функция `str()` может также использоваться как функция\n",
"преобразования. В этом случае первый аргумент должен быть строкой или\n",
"объектом, который можно преобразовать в строку, а, кроме того, функции\n",
"может быть передано до двух необязательных строковых аргументов, один\n",
"из которых определяет используемую кодировку, а второй определяет\n",
"порядок обработки ошибок кодирования.\n",
"\n",
"Литералы строк создаются с использованием кавычек или апострофов, при\n",
"этом важно, чтобы с обоих концов литерала использовались кавычки\n",
"одного и того же типа. В дополнение к этому мы можем использовать\n",
"строки в тройных кавычках, то есть строки, которые начинаются и\n",
"заканчиваются тремя символами кавычки (либо тремя кавычками, либо\n",
"тремя апострофами). Например:"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"text = \"\"\"Строки в тройных кавычках могут включать 'апострофы' и \"кавычки\"\n",
"без лишних формальностей. Мы можем даже экранировать символ перевода строки \\,\n",
"благодаря чему данная конкретная строка будет занимать всего две строки.\"\"\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Если нам потребуется использовать кавычки в строке, это можно сделать\n",
"без лишних формальностей при условии, что они отличаются от кавычек,\n",
"ограничивающих строку; в противном случае символы кавычек или\n",
"апострофов внутри строки следует экранировать:"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"a = \"Здесь 'апострофы' можно не экранировать, а \\\"кавычки\\\" придется.\"\n",
"b = 'Здесь \\'апострофы\\' придется экранировать, а \"кавычки\" не обязательно.'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"В языке Python символ перевода строки интерпретируется как завершающий\n",
"символ инструкции, но не внутри круглых скобок (`()`), квадратных\n",
"скобок (`[]`), фигурных скобок (`{}`) и строк в тройных кавычках. \n",
"Символы перевода строки могут без лишних формальностей использоваться\n",
"в строках в тройных кавычках, и мы можем включать символы перевода\n",
"строки в любые строковые литералы с помощью экранированной\n",
"последовательности `\\n`.\n",
"\n",
"Все экранированные последовательности, допустимые в языке Python,\n",
"перечислены в табл. 2.6.\n",
"\n",
"\n",
"## Таблица 5 : Функции и константы модуля `math` <div id=\"datatype:tbl:5\"></div>\n",
"\n",
"\n",
"<table border=\"1\">\n",
"<thead>\n",
"<tr><th align=\"left\">Последовательность</th> <th align=\"left\"> Значение </th> </tr>\n",
"</thead>\n",
"<tbody>\n",
"<tr><td align=\"left\"> <code>\\переводстроки</code> </td> <td align=\"left\"> Экранирует (то есть игнорирует) символ перевода строки </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\\\</code> </td> <td align=\"left\"> Символ обратного слеша (<code>\\</code>) </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\'</code> </td> <td align=\"left\"> Апостроф (<code>'</code>) </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\\"</code> </td> <td align=\"left\"> Кавычка (<code>\"</code>) </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\a</code> </td> <td align=\"left\"> Символ ASCII «сигнал» (bell, BEL) </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\b</code> </td> <td align=\"left\"> Символ ASCII «забой» (backspace, BS) </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\f</code> </td> <td align=\"left\"> Символ ASCII «перевод формата» (formfeed, FF) </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\n</code> </td> <td align=\"left\"> Символ ASCII «перевод строки» (linefeed, LF) </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\N{название}</code> </td> <td align=\"left\"> Символ Юникода с заданным названием </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\ooo</code> </td> <td align=\"left\"> Символ с заданным восьмеричным кодом </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\r</code> </td> <td align=\"left\"> Символ ASCII «возврат каретки» (carriage return, CR) </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\t</code> </td> <td align=\"left\"> Символ ASCII «табуляция» (tab, TAB) </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\uhhhh</code> </td> <td align=\"left\"> Символ Юникода с указанным 16-битовым шестнадцатеричным значением </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\Uhhhhhhhh</code> </td> <td align=\"left\"> Символ Юникода с указанным 32-битовым шестнадцатеричным значением </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\v</code> </td> <td align=\"left\"> Символ ASCII «вертикальная табуляция» (vertical tab, VT) </td> </tr>\n",
"<tr><td align=\"left\"> <code>\\xhh</code> </td> <td align=\"left\"> Символ с указанным 8-битовым шестнадцатеричным значением </td> </tr>\n",
"</tbody>\n",
"</table>\n",
"\n",
"\n",
"Если потребуется записать длинный строковый литерал, занимающий\n",
"две или более строк, но без использования тройных кавычек, то можно\n",
"использовать один из приемов, показанных ниже:"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"t = \"Это не самый лучший способ объединения двух длинных строк, \" + \\\n",
" \"потому что он основан на использовании неуклюжего экранирования\"\n",
"s = (\"Это отличный способ объединить две длинные строки, \"\n",
" \" потому что он основан на конкатенации строковых литералов.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Обратите внимание, что во втором случае для создания единственного\n",
"выражения мы должны были использовать круглые скобки без этих\n",
"скобок переменной s была бы присвоена только первая строка, а наличие\n",
"второй строки вызвало бы исключение `IndentationError`. \n",
"\n",
"## Сравнение строк\n",
"<div id=\"datatype:strings:compare\"></div>\n",
"\n",
"Строки поддерживают обычные операторы сравнения `<`, `<=`, `==`, `!=`,\n",
"`>` и `>=`. Эти операторы выполняют побайтовое сравнение строк в памяти.\n",
"К сожалению, возникают две проблемы при сравнении, например,\n",
"строк в отсортированных списках. Обе проблемы проявляются во всех\n",
"языках программирования и не являются характерной особенностью\n",
"Python.\n",
"\n",
"Первая проблема связана с тем, что символы Юникода могут быть\n",
"представлены двумя и более последовательностями байтов.\n",
"\n",
"Вторая проблема заключается в том, что порядок сортировки некоторых\n",
"символов зависит от конкретного языка.\n",
"\n",
"## Получение срезов строк\n",
"<div id=\"datatype:strings:slices\"></div>\n",
"\n",
"Отдельные элементы последовательности, а, следовательно, и отдельные\n",
"символы в строках, могут извлекаться с помощью оператора доступа к\n",
"элементам (`[]`). В действительности этот оператор намного более\n",
"универсальный и может использоваться для извлечения не только одного\n",
"символа, но и целых комбинаций (подпоследовательностей) элементов или\n",
"символов, когда этот оператор используется в контексте оператора\n",
"извлечения среза.\n",
"\n",
"Для начала мы рассмотрим возможность извлечения отдельных\n",
"символов. Нумерация позиций символов в строках начинается с 0 и\n",
"продолжается до значений длины строки минус 1. Однако допускается\n",
"использовать и отрицательные индексы в этом случае отсчет начинается\n",
"с последнего символа и ведется в обратном направлении к первому \n",
"символу. На рис. [datatype:strings:fig:1](#datatype:strings:fig:1) показано, как нумеруются\n",
"позиции символов в строке, если предположить, что было выполнено\n",
"присваивание `s = \"Light ray\"`. \n",
"\n",
"<!-- dom:FIGURE: [fig-datatype/strings_1.png, width=600 frac=1.0] Номера позиций символов в строке <div id=\"datatype:strings:fig:1\"></div> -->\n",
"<!-- begin figure -->\n",
"<div id=\"datatype:strings:fig:1\"></div>\n",
"![Номера позиций символов в строке](fig-datatype/strings_1.png)<!-- end figure -->\n",
"\n",
"\n",
"Отрицательные индексы удивительно удобны, особенно индекс `-1`,\n",
"который всегда соответствует последнему символу строки. Попытка\n",
"обращения к индексу, находящемуся за пределами строки (или к любому\n",
"индексу в пустой строке), будет вызывать исключение `IndexError`.\n",
"Оператор получения среза имеет три формы записи:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```Python\n",
" seq[start]\n",
" seq[start:end]\n",
" seq[start:end:step]\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ссылка `seq` может представлять любую последовательность, такую как\n",
"список, строку или кортеж. Значения `start`, `end` и `step` должны быть\n",
"целыми числами (или переменными, хранящими целые числа). Первая форма\n",
"— это запись оператора доступа к элементам: с ее помощью извлекается\n",
"элемент последовательности с индексом `start`. Вторая форма записи\n",
"извлекает подстроку, начиная с элемента с индексом `start` и заканчивая\n",
"элементом с индексом `end`, *не включая* его.\n",
"\n",
"При использовании второй формы записи (с одним двоеточием) мы можем\n",
"опустить любой из индексов. Если опустить начальный индекс, по\n",
"умолчанию будет использоваться значение `0`. Если опустить конечный\n",
"индекс, по умолчанию будет использоваться значение `len(seq)`. \n",
"Это означает, что если опустить оба индекса, например, `s[:]`, это будет\n",
"равносильно выражению `s[0:len(s)]`, и в результате будет извлечена,\n",
"то есть скопирована, последовательность целиком.\n",
"\n",
"На рис. [datatype:strings:fig:2](#datatype:strings:fig:2) приводятся некоторые примеры\n",
"извлечения срезов из строки `s`, которая получена в результате\n",
"присваивания `s = \"The waxwork man\"`.\n",
"\n",
"<!-- dom:FIGURE: [fig-datatype/strings_2.png, width=600 frac=1.0] Извлечение срезов из последовательности <div id=\"datatype:strings:fig:2\"></div> -->\n",
"<!-- begin figure -->\n",
"<div id=\"datatype:strings:fig:2\"></div>\n",
"![Извлечение срезов из последовательности](fig-datatype/strings_2.png)<!-- end figure -->\n",
"\n",
"\n",
"Один из способов вставить подстроку в строку состоит в смешивании\n",
"операторов извлечения среза и операторов конкатенации. Например:"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"s = s[:12] + \"wo\" + s[12:]"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"s"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Кроме того, поскольку текст «wo» присутствует в оригинальной строке,\n",
"тот же самый эффект можно было бы получить путем присваивания значения\n",
"выражения `s[:12] + s[7:9] + s[12:]`.\n",
"\n",
"Оператор конкатенации `+` и добавления подстроки `+=` не\n",
"особенно эффективны, когда в операции участвует множество строк. Для\n",
"объединения большого числа строк обычно лучше использовать метод\n",
"`str.join()`, с которым мы познакомимся в следующем подразделе.\n",
"\n",
"Третья форма записи (с двумя двоеточиями) напоминает вторую форму, но\n",
"в отличие от нее значение `step` определяет, с каким шагом следует\n",
"извлекать символы. Как и при использовании второй формы записи, мы\n",
"можем опустить любой из индексов. Если опустить начальный \n",
"индекс, по умолчанию будет использоваться значение `0`, при условии,\n",
"что задано неотрицательное значение step; в противном случае начальный\n",
"индекс по умолчанию получит значение `-1`. Если опустить конечный\n",
"индекс, по умолчанию будет использоваться значение `len(seq)`, \n",
"при условии, что задано неотрицательное значение step; в противном\n",
"случае конечный индекс по умолчанию получит значение индекса перед\n",
"началом строки. Мы не можем опустить значение step, и оно не может\n",
"быть равно нулю если задание шага не требуется, то следует\n",
"использовать вторую форму записи (с одним двоеточием), в которой шаг \n",
"выбора элементов не указывается.\n",
"\n",
"На рис. [datatype:strings:fig:3](#datatype:strings:fig:3) приводится пара примеров извлечения разреженных срезов из\n",
"строки `s`, которая получена в результате присваивания\n",
"`s = \"he ate camel food\"`.\n",
"\n",
"<!-- dom:FIGURE: [fig-datatype/strings_3.png, width=600 frac=1.0] Извлечение разреженных срезов <div id=\"datatype:strings:fig:3\"></div> -->\n",
"<!-- begin figure -->\n",
"<div id=\"datatype:strings:fig:3\"></div>\n",
"![Извлечение разреженных срезов](fig-datatype/strings_3.png)<!-- end figure -->\n",
"\n",
"\n",
"Здесь мы использовали значения по умолчанию для начального и ко-\n",
"нечного индексов, то есть извлечение среза s[:: 2] начинается с по-\n",
"следнего символа строки и извлекается каждый второй символ по на-\n",
"правлению к началу строки. Аналогично извлечение среза s[::3] на-\n",
"чинается с первого символа строки и извлекается каждый третий сим-\n",
"вол по направлению к концу строки.\n",
"Существует возможность комбинировать индексы с размером шага,\n",
"как показано на рис. [datatype:strings:fig:4](#datatype:strings:fig:4).\n",
"\n",
"<!-- dom:FIGURE: [fig-datatype/strings_4.png, width=800 frac=1.0] Извлечение срезов из последовательности с определенным шагом <div id=\"datatype:strings:fig:4\"></div> -->\n",
"<!-- begin figure -->\n",
"<div id=\"datatype:strings:fig:4\"></div>\n",
"![Извлечение срезов из последовательности с определенным шагом](fig-datatype/strings_4.png)<!-- end figure -->\n",
"\n",
"\n",
"Операция извлечения элементов с определенным шагом часто применяется к\n",
"последовательностям, отличным от строк, но один из ее вариантов часто\n",
"применяется к строкам:\n",
"\n",
"## Операторы и методы строк\n",
"<div id=\"datatype:strings:operat\"></div>\n",
"\n",
"Поскольку строки относятся к категории неизменяемых\n",
"последовательностей, все функциональные возможности, применимые к\n",
"неизменяемым последовательностям, могут использоваться и со\n",
"строками. Сюда входят оператор проверки на вхождение `in`, оператор\n",
"конкатенации `+`, оператор добавления в конец `+=`, оператор\n",
"дублирования `*` и комбинированный оператор присваивания с\n",
"дублированием `*=`. Применение всех этих операторов в контексте строк\n",
"мы обсудим в этом подразделе, а также обсудим большинство строковых\n",
"методов. В табл. 2.7 приводится перечень некоторых строковых методов.\n",
"\n",
"Так как строки являются последовательностями, они являются объектами,\n",
"имеющими «размер», и поэтому мы можем вызывать функцию `len()`,\n",
"передавая ей строки в качестве аргумента. Возвращаемая функцией длина\n",
"представляет собой количество символов в строке (ноль для пустых\n",
"строк).\n",
"\n",
"Мы уже знаем, что перегруженная версия оператора `+` для строк\n",
"выполняет операцию конкатенации. В случаях, когда требуется объединить\n",
"множество строк, лучше использовать метод `str.join()`. Метод \n",
"принимает в качестве аргумента последовательность (то есть список\n",
"или кортеж строк) и объединяет их в единую строку, вставляя между\n",
"ними строку, относительно которой был вызван метод. Например:"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"treatises = [\"Arithmetica\", \"Conics\", \"Elements\"]\n",
"\" \".join(treatises)"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"\"-<>-\".join(treatises)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"\"\".join(treatises)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Метод `str.join()` может также использоваться в комбинации со\n",
"встроенной функцией `reversed()`, которая переворачивает строку \n",
"например, `\"\".join(reversed(s))`, хотя тот же результат может быть\n",
"получен более кратким оператором извлечения разреженного среза \n",
"например, `s[:: 1]`.\n",
"\n",
"Оператор `*` обеспечивает возможность дублирования строки:"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"s = \"=\" * 5\n",
"print(s)"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"s *= 10\n",
"print(s)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Как показано в примере, мы можем также использовать комбинированный\n",
"оператор присваивания с дублированием. \n",
"\n",
"# Форматирование строк с помощью метода `str.format()`\n",
"<div id=\"datatype:strings:format\"></div>\n",
"\n",
"Метод `str.format()` представляет собой очень мощное и гибкое средство\n",
"создания строк. Использование метода `str.format()` в простых случаях\n",
"не вызывает сложностей, но для более сложного форматирования нам\n",
"необходимо изучить синтаксис форматирования.\n",
"\n",
"Метод `str.format()` возвращает новую строку, замещая поля в\n",
"контекстной строке соответствующими аргументами. Например:"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"\"The novel '{0}' was published in {1}\".format(\"Hard Times\", 1854)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Каждое замещаемое поле идентифицируется именем поля в фигурных\n",
"скобках. Если в качестве имени поля используется целое число, оно\n",
"определяет порядковый номер аргумента, переданного методу\n",
"`str.format()`. Поэтому в данном случае поле с именем `0` было замещено\n",
"первым аргументом, а поле с именем `1` вторым аргументом. \n",
"\n",
"Если бы нам потребовалось включить фигурные скобки в строку формата,\n",
"мы могли бы сделать это, дублируя их, как показано ниже:"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"\"{{{0}}} {1} ;-}}\".format(\"I'm in braces\", \"I'm not\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Если попытаться объединить строку и число, интерпретатор Python\n",
"совершенно справедливо возбудит исключение `TypeError`. Но это легко\n",
"можно сделать с помощью метода `str.format()`:"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"\"{0}{1}\".format(\"The amount due is $\", 200)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"С помощью `str.format()` мы также легко можем объединять строки\n",
"(хотя для этой цели лучше подходит метод `str.join()`):"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"x = \"three\"\n",
"s =\"{0} {1} {2}\"\n",
"s = s.format(\"The\", x, \"tops\")\n",
"s"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- Local Variables: -->\n",
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
"<!-- doconce-section-nickname: \"strings\" -->\n",
"<!-- End: -->\n",
"# Примеры\n",
"<div id=\"datatype:examples\"></div>\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"## `quadratic.py`\n",
"<div id=\"datatype:examples:quadratic\"></div>\n",
"\n",
"Квадратные уравнения это уравнения вида $ax^2 + bx + c = 0$, где $a \\ne 0$,\n",
"описывающие параболу. Корни таких уравнений находятся по формуле"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Часть формулы $b^2 4ac$ называется дискриминантом если это\n",
"положительная величина, уравнение имеет два действительных корня, если\n",
"дискриминант равен нулю уравнение имеет один действительный корень,\n",
"и в случае отрицательного значения уравнение имеет два комплексных\n",
"корня. Мы напишем программу, которая будет принимать от пользователя\n",
"коэффициенты $a$, $b$ и $c$ (коэффициенты $b$ и c могут быть равны\n",
"нулю) и затем вычислять и выводить его корень или корни.\n",
"\n",
"\n",
"Для начала посмотрим, как работает программа:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"С коэффициентами $1.5$, $-3$ и $6$ программа выведет (некоторые цифры\n",
"обрезаны):\n",
"\n",
"<!-- Local Variables: -->\n",
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
"<!-- doconce-section-nickname: \"examples\" -->\n",
"<!-- End: -->\n",
"\n",
"\n",
"\n",
"\n",
"<!-- Local Variables: -->\n",
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
"<!-- End: -->"
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 2
}