# 3. Неформальное введение в Python

В следующих примерах ввод и вывод отличаются по наличию или отсутствию приглашений (>>> и …). Чтобы повторить пример, вы должны ввести всё, что в нём написано после приглашения, когда оно появится. Строки, которые не начинаются с приглашения, — это вывод интерпретатора. Обратите внимание, что вторичное приглашение, стоящее в примере на отдельной строке, означает, что вы должны ввести пустую строку. Это используется для завершения многострочной команды.

Вы можете использовать кнопку «Копировать» (она появляется в правом верхнем углу при наведении или нажатии на пример кода), которая убирает подсказки и опускает вывод, чтобы скопировать и вставить исходные строки кода в свой интерпретатор.

Многие примеры в этом руководстве, даже те, что вводятся в интерактивной оболочке, содержат комментарии. Комментарии в Python начинаются со знака решётки, `#`, и продолжаются до конца физической строки. Комментарий может стоять в начале строки или после пробелов или кода, но не внутри строкового литерала. Знак решётки внутри строкового литерала — это просто символ решётки. Поскольку комментарии предназначены для пояснения кода и не интерпретируются Python, их можно опускать при наборе примеров.

Несколько примеров:

    # это первый комментарий
    spam = 1  # а это второй комментарий
              # ... и теперь третий!
    text = "# Это не комментарий, потому что он внутри кавычек."

## 3.1. Использование Python как калькулятор

Давайте попробуем несколько простых команд Python. Запустите интерпретатор и дождитесь основного приглашения, `>>>`. (Это не должно занять много времени.)

### 3.1.1. Числа

Интерпретатор работает как простой калькулятор: можно ввести в него выражение, и он выведет его значение. Синтаксис выражений прост: для выполнения арифметических операций можно использовать операторы `+`, `-`, `*` и `/`, а для группировки — скобки (`()`). Например:

    >>> 2 + 2
    4
    >>> 50 - 5*6
    20
    >>> (50 - 5*6) / 4
    5.0
    >>> 8 / 5 # деление всегда возвращает число с плавающей точкой
    1.6

Целые числа (например `2`, `4`, `20`) имеют тип `int`, числа с дробной частью (например `5.0`, `1.6`) имеют тип `float`. Подробнее о числовых типах мы поговорим позже в этом учебнике.

Деление (`/`) всегда возвращает значение с плавающей точкой. Чтобы выполнить деление с округлением вниз и получить целочисленный результат, вы можете использовать оператор `//`; для вычисления остатка вы можете использовать `%`:

    >>> 17 / 3  # классическое деление возвращает число с плавающей точкой
    5.666666666666667
    >>>
    >>> 17 // 3  # деление с округлением вниз отбрасывает дробную часть
    5
    >>> 17 % 3  # оператор % возвращает остаток от деления
    2
    >>> 5 * 3 + 2  # округлённая вниз частное * делитель + остаток
    17

В Python можно использовать оператор `**` для вычисления степеней [1]:

    >>> 5 ** 2  # 5 в квадрате
    25
    >>> 2 ** 7  # 2 в седьмой степени
    128

Знак равенства (`=`) используется для присвоения значения переменной. После присваивания результат не выводится — интерпретатор просто переходит к следующему приглашению.

    >>> width = 20
    >>> height = 5 * 9
    >>> width * height
    900

Если переменная не «определена» (ей не присвоено значение), попытка её использования приведёт к ошибке:

    >>> n  # попробуем обратиться к неопределённой переменной
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'n' is not defined

В Python есть полноценная поддержка чисел с плавающей точкой; операторы с операндами разных типов преобразуют целое число в число с плавающей точкой:

    >>> 4 * 3.75 - 1
    14.0

В интерактивном режиме, последнее напечатанное выражение присваивается переменной `_`. Это означает, что при использовании Python в качестве настольного калькулятора продолжать вычисления становится немного проще, например:

    >>> tax = 12.5 / 100
    >>> price = 100.50
    >>> price * tax
    12.5625
    >>> price + _
    113.0625
    >>> round(_, 2)
    113.06

Эту переменную следует рассматривать как доступную только для чтения. Не присваивайте ей значение явно — иначе вы создадите обычную локальную переменную с тем же именем, скрыв встроенную переменную с её магическим поведением.

В дополнение к `int` и `float`, Python поддерживает другие типы чисел, такие, как `Decimal` и `Fraction`. Python также имеет встроенную поддержку :ref:` комплексных чисел <typesnumeric>`, и использует суффиксы `j` или `J` для обозначения мнимой части (например `3+5j`).

### 3.1.2. Текст

Python может работать с текстом (представленным типом `str`, так называемыми «строками») так же, как и числами. К тексту относятся символы «`!`», слова «`rabbit`», имена «`Paris`», предложения «`Got your back.`», и т.д. «`Yay! :)`». Строки можно заключать как в одинарные кавычки (`'...'`), так и в двойные (`"..."`) — результат будет одинаковым [2].

    >>> 'спам яйца' # одинарные кавычки
    'спам яйца'
    >>> "Парижский кролик тебя прикроет :)! Ура!"  # двойные кавычки
    'Парижский кролик тебя прикроет :)! Ура!'
    >>> '1975' # цифры и числа в кавычках — это тоже строки
    '1975'

Чтобы вставить кавычку внутри строки, нужно экранировать её, поставив перед ней `\`. В качестве альтернативы можно использовать другой тип кавычек:

    >>> 'doesn\'t'  # use \' to escape the single quote...
    "doesn't"
    >>> "doesn't"  # ...or use double quotes instead
    "doesn't"
    >>> '"Yes," they said.'
    '"Yes," they said.'
    >>> "\"Yes,\" they said."
    '"Yes," they said.'
    >>> '"Isn\'t," they said.'
    '"Isn\'t," they said.'

В оболочке Python определение строки и то, как она выводится, может выглядеть по-разному. Функция `print()` обеспечивает более читаемый вывод, опуская окружающие кавычки и печатая экранированные и специальные символы:

    >>> s = 'Первая строка.\nВторая строка.'  # \n означает перевод строки
    >>> s  # без print() специальные символы показываются как есть
    Первая строка.\nВторая строка.'
    >>> print(s)  # с print() специальные символы интерпретируются, и \n создаёт новую строку
    Первая строка.
    Вторая строка.

Если вы не хотите, чтобы символы, перед которыми стоит `\`, интерпретировались как специальные, можно использовать сырые строки, добавив `r` перед открывающей кавычкой:

    >>> print('C:\this\name')  # здесь \t означает табуляцию, а \n — перевод строки
    C:      his
    ame
    >>> print(r'C:\this\name')  #  обратите внимание на r перед кавычкой
    C:\this\name

У сырых строк есть одна тонкая особенность: сырая строка не может заканчиваться нечётным количеством символов `\`. Подробнее об этом, а также о возможных обходных путях см. :ref:` соответствующий пункт ЧаВо <faq-programming-raw-string-backslash>`.

Строковые литералы могут занимать несколько строк. Один из способов — использовать тройные кавычки: `"""..."""` или `'''...'''`. Символы конца строки автоматически включаются в строку, но их можно предотвратить, добавив `\` в конце строки. В следующем примере начальный перевод строки не включён:

    >>> print("""\
    ... Usage: thingy [OPTIONS]
    ...      -h                        Показать это сообщение о применении
    ...      -H hostname               Имя хоста для подключения
    ... """)
    Usage: thingy [OPTIONS]
         -h                        Показать это сообщение о применении
         -H hostname               Имя хоста для подключения

    >>>

Строки можно конкатенировать (склеивать) с помощью оператора `+` и повторять с помощью `*`:

    >>> # три раза 'un', затем 'ium'
    >>> 3 * 'un' + 'ium'
    'unununium'

Два или более строковых литерала (то есть заключённых в кавычки) подряд автоматически объединяются.

    >>> 'Py' 'thon'
    'Python'

Эта возможность особенно полезна, когда вы хотите разбить длинную строку:

    >>> text = ('Поместите несколько строк в круглые скобки,  '
    ...         'чтобы они были объединены вместе.')
    >>> text
    'Поместите несколько строк в круглые скобки, чтобы они были объединены вместе.'

Это работает только с литералами, но не с переменными или выражениями:

    >>> prefix = 'Py'
    >>> prefix 'thon'  # нельзя объединять переменную и строковый литерал
      File "<stdin>", line 1
        prefix 'thon'
               ^^^^^^
    SyntaxError: invalid syntax
    >>> ('un' * 3) 'ium'
      File "<stdin>", line 1
        ('un' * 3) 'ium'
                   ^^^^^
    SyntaxError: invalid syntax

Если вы хотите объединить переменные или переменную и литерал, используйте `+`:

    >>> prefix + 'thon'
    'Python'

Строки можно индексировать (обращаться к символу по индексу), при этом первый символ имеет индекс 0. Отдельного символьного типа в Python нет — символом считается строка длины один:

    >>> word = 'Python'
    >>> word[0]  # символ на позиции 0
    'P'
    >>> word[5]  # символ на позиции 5
    'n'

Индексы могут также иметь отрицательные значения и начинают отсчитываться справа:

    >>> word[-1]  # последний символ
    'n'
    >>> word[-2]  # предпоследний символ
    'o'
    >>> word[-6]
    'P'

Обратите внимание, что поскольку -0 равно 0, отрицательные индексы начинаются с -1.

В дополнение к индексации поддерживаются и срезы. В то время как индексация используется для получения отдельных символов, срез позволяет получить подстроку:

    >>> word[0:2]  # символы с позиции 0 (включительно) по 2 (не включая)
    'Py'
    >>> word[2:5]  # символы с позиции 2 (включительно) по 5 (не включая)
    'tho'

У срезов есть удобные значения по умолчанию: пропущенный первый индекс принимается равным нулю, пропущенный второй — длине разрезаемой строки.

    >>> word[:2]   # символы с начала до позиции 2 (не включая)
    'Py'
    >>> word[4:]   # символы с позиции 4 (включительно) до конца
    'on'
    >>> word[-2:]  # символы со второго с конца (включительно) до конца
    'on'

Обратите внимание, что начало среза всегда включается, а конец — всегда исключается. Это гарантирует, что выражение `s[:i] + s[i:]` всегда равно `s`:

    >>> word[:2] + word[2:]
    'Python'
    >>> word[:4] + word[4:]
    'Python'

Один из способов запомнить, как работают срезы, — представить, что индексы указывают между символами, и левая граница первого символа имеет индекс 0. Тогда правая граница последнего символа строки длины n имеет индекс n, например:

     +---+---+---+---+---+---+
     | P | y | t | h | o | n |
     +---+---+---+---+---+---+
     0   1   2   3   4   5   6
    -6  -5  -4  -3  -2  -1

Верхняя строка чисел показывает позиции индексов 0…6 в строке; нижняя строка — соответствующие отрицательные индексы. Срез от i до j состоит из всех символов между границами, помеченными i и j соответственно.

Для неотрицательных индексов длина среза равна разности индексов, если оба они находятся в допустимых пределах. Например, длина `word[1:3]` равна 2.

Попытка использовать слишком большой индекс приведёт к ошибке:

    >>> word[42]  # слово содержит всего 6 символов
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IndexError: string index out of range

Однако выход за границы допустимого диапазона индексов в случае срезов обрабатывается корректно:

    >>> word[4:42]
    'on'
    >>> word[42:]
    ''

Строки в Python нельзя изменять — они immutable. Поэтому попытка присвоить значение элементу по индексу приводит к ошибке:

    >>> word[0] = 'J'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'str' object does not support item assignment
    >>> word[2:] = 'py'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'str' object does not support item assignment

Если вам нужна другая строка, вам следует создать новую:

    >>> 'J' + word[1:]
    'Jython'
    >>> word[:2] + 'py'
    'Pypy'

Встроенная функция `len()` возвращает длину строки:

    >>> s = 'суперкалифрагилистикэкспиалидоушес'
    >>> len(s)
    34

См. также

Text Sequence Type — str

  Строки являются примером типа последовательностей и поддерживают общие для них операции.

String Methods

  Строки поддерживают множество методов для простых преобразований и поиска.

f-строки

  Строковые литералы со встроенными выражениями.

Format string syntax

  Информацию о форматировании строк методом `str.format()`.

printf-style String Formatting

  Старые операции форматирования, которые выполняются при применении оператора `%` к строке, описаны здесь подробнее.

### 3.1.3. Списки

Python поддерживает ряд составных типов данных, которые используются для объединения других значений. Наиболее универсальный из них — список. Он записывается как набор значений (элементов), разделённых запятыми, заключённых в квадратные скобки. Списки могут содержать элементы разных типов, но обычно элементы имеют один и тот же тип.

    >>> squares = [1, 4, 9, 16, 25]
    >>> squares
    [1, 4, 9, 16, 25]

Подобно строкам (и всем другим встроенным типам sequence), списки можно индексировать и брать из них срезы:

    >>> squares[0]  # индексация возвращает элемент
    1
    >>> squares[-1]
    25
    >>> squares[-3:]  # срез возвращает новый список
    [9, 16, 25]

Списки также поддерживают такие операции, как конкатенация:

    >>> squares + [36, 49, 64, 81, 100]
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

В отличие от строк, которые являются immutable, списки — это mutable тип данных. Это значит, что их содержимое можно изменить.:

    >>> cubes = [1, 8, 27, 65, 125]  # здесь есть ошибка
    >>> 4 ** 3  # куб числа 4 равен 64, а не 65!
    64
    >>> cubes[3] = 64  # заменяем неверное значение
    >>> cubes
    [1, 8, 27, 64, 125]

Вы также можете добавлять новые элементы в конец списка, используя метод `list.append()` (подробнее о методах мы поговорим позже):

    >>> cubes.append(216)  # добавляем куб числа 6
    >>> cubes.append(7 ** 3)  # и куб числа 7
    >>> cubes
    [1, 8, 27, 64, 125, 216, 343]

Простое присваивание в Python никогда не копирует данные. Когда вы присваиваете список переменной, переменная начинает ссылаться на существующий список. Любые изменения, которые вы вносите в список через одну переменную, будут видны и через все другие переменные, которые ссылаются на него.:

    >>> rgb = ["Red", "Green", "Blue"]
    >>> rgba = rgb
    >>> id(rgb) == id(rgba)  # обе переменные ссылаются на один объект
    True
    >>> rgba.append("Alph")
    >>> rgb
    ["Red", "Green", "Blue", "Alph"]

Все операции среза возвращают новый список, содержащий запрошенные элементы. Это означает, что следующий срез возвращает поверхностную копию списка:

    >>> correct_rgba = rgba[:]
    >>> correct_rgba[-1] = "Alpha"
    >>> correct_rgba
    ["Red", "Green", "Blue", "Alpha"]
    >>> rgba
    ["Red", "Green", "Blue", "Alph"]

Присваивание срезам также возможно, и это может даже менять размер списка или полностью его очищать.

    >>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    >>> letters
    ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    >>> # заменяем несколько значений
    >>> letters[2:5] = ['C', 'D', 'E']
    >>> letters
    ['a', 'b', 'C', 'D', 'E', 'f', 'g']
    >>> # теперь удаляем их
    >>> letters[2:5] = []
    >>> letters
    ['a', 'b', 'f', 'g']
    >>> # очищаем список, заменяя все элементы пустым списком
    >>> letters[:] = []
    >>> letters
    []

Встроенная функция `len()` также применима к спискам:

    >>> letters = ['a', 'b', 'c', 'd']
    >>> len(letters)
    4

Можно создавать вложенные списки (то есть списки, содержащие другие списки), например:

    >>> a = ['a', 'b', 'c']
    >>> n = [1, 2, 3]
    >>> x = [a, n]
    >>> x
    [['a', 'b', 'c'], [1, 2, 3]]
    >>> x[0]
    ['a', 'b', 'c']
    >>> x[0][1]
    'b'

## 3.2. Первые шаги в программировании

Конечно, мы можем использовать Python для более сложных задач, чем складывать два и два. Например, мы можем выписать начальную подпоследовательность ряда Фибоначчи следующим образом:

    >>> # Ряд Фибоначчи:
    >>> # сумма двух элементов определяет следующий
    >>> a, b = 0, 1
    >>> while a < 10:
    ...     print(a)
    ...     a, b = b, a+b
    ...
    0
    1
    1
    2
    3
    5
    8

Этот пример представляет несколько новых возможностей.

- Первая строка содержит множественное присваивание: переменные `a` и `b` одновременно получают новые значения, 0 и 1. В последней строке это используется снова, демонстрируя, что выражения справа вычисляются полностью до выполнения любого присваивания. Выражение с правой стороны вычисляется слева направо.

- Цикл `while` выполняется до тех пор, пока условие (здесь: `a < 10`) остаётся истинным. В Python, как и в C, любое ненулевое целое значение равно true; ноль равен false. Условием также может быть строка или список, фактически любая последовательность. Всё, что имеет ненулевую длину, является истинным, пустые последовательности — ложными. В примере используется простое сравнение. Стандартные операторы сравнения записываются так же, как и в C: `<` (меньше), `>` (больше), `==` (равно), `<=` (меньше или равно), `>=` (больше или равно) и `!=` (не равно).

- Тело цикла должно иметь отступ — это способ группировать инструкции в Python. В интерактивной оболочке вы должны вводить табуляцию или пробелы для каждой строки с отступом. На практике более сложные программы готовят в текстовом редакторе, приличные из которых имеют средства автоматического отступа. Когда составная инструкция вводится интерактивно, за ней должна следовать пустая строка, чтобы обозначить завершение (парсер не может угадать, что вы ввели последнюю строку). Обратите внимание, что каждая строка внутри одного блока должна иметь одинаковый отступ.

- Функция `print()` выводит значение переданных ей аргументов. Она отличается от простого вывода выражения (как мы делали ранее в примерах с калькулятором) тем, как она обрабатывает несколько аргументов, числа с плавающей точкой и строки. Строки выводятся без кавычек, а между элементами автоматически вставляется пробел, что позволяет красиво форматировать вывод, например:

      >>> i = 256*256
      >>> print('Значение i равно', i)
      Значение i равно 65536

  Именованный аргумент end позволяет избежать перевода строки после вывода или завершить вывод другой строкой:

      >>> a, b = 0, 1
      >>> while a < 1000:
      ...     print(a, end=',')
      ...     a, b = b, a+b
      ...
      0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,

Примечания

[1]

Так как `**` имеет более высокий приоритет, чем `-`, `-3**2` будет интерпретировано как `-(3**2)` и даст результат `-9`. Чтобы этого избежать, и получить `9`, вы можете использовать `(-3)**2`.

[2]

В отличие от других языков, специальные символы как `\n` имеют ожинаковое значение как с одинарными (`'...'`), так и с двойными (`"..."`) кавычками. Единственное отличие между ними состоит в том, что внутри одинарных кавычек вам не нужно экранировать `"` (но вам нужно экранировать `\'`) и наоборот.