С помощью чего меняется порядок вычислений в python
Перейти к содержимому

С помощью чего меняется порядок вычислений в python

  • автор:

Приоритеты операторов Python

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

Оператор возведения в степень исключение из этого правила. Из двух операторов ** сначала выполнится правый, а потом левый.

Операторы Описание
() Скобки
** Возведение в степень
+x , -x , ~x Унарные плюс, минус и битовое отрицание
* , / , // , % Умножение, деление, целочисленное деление, остаток от деления
+ , — Сложение и вычитание
> Битовые сдвиги
& Битовое И
^ Битовое исключающее ИЛИ ( XOR )
| Битовое ИЛИ
== , != , > , >= , < , Сравнение, проверка идентичности, проверка вхождения
not Логическое НЕ
and Логическое И
or Логическое ИЛИ

Хотите выучить Python на практике?

С нуля и до создания компьютерной игры

Собственный онлайн-тренажер с проверкой практических задач

Просто про функции и их аргументы в Python

Функции существуют в большинстве современных языков программирования. В императивных языках (к которым относится и Python) функция — это набор инструкций, объединенных для выполнения одной задачи. Блоки кода, однажды оформленные в виде функций, можно использовать в коде многократно. Поэтому разработчики охотно применяют этот подход на практике, чтобы облегчить работу себе и своему приложению.

Високорівневий курс від laba: Фінансовий аналіз.
Оцінюйте фінансову стабільність та перспективи.

Редакция highload.today разобралась, как это работает, как создавать функции Python, на какие разновидности они делятся, как вызывать функции и передавать в них аргументы. Теперь мы готовы помочь разобраться в этом вам. И… да, примеры кода обязательно будут.

функции и их аргументы в Python

1. Что такое функция в Python

В предыдущем абзаце уже шла речь о том, что функции Python делятся на разновидности. Мы рассмотрим две классификации:

    встроенные / не встроенные (пользовательские);

Стратегічний курс від laba: Business English для фінансистів.
Завоюйте світовий ринок.

Отличия между ними сводятся не только к синтаксису и способу использования. Не менее важно, что работают они тоже по-разному (далее мы в этом убедимся).

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

Встроенная функция Python Краткое описание
len() вычисляет длину (количество элементов) последовательности (например, списка)
next() возвращает следующий по порядку элемент последовательности (например, списка)
reversed() меняет порядок элементов последовательности на обратный

В языке Python десятки таких функций, и внутренняя реализация многих из них очень сложна. Но об этом за вас уже позаботились разработчики языка, поэтому пользуйтесь с удовольствием — как говорится, бесплатно и без регистрации. Разобраться во всех тонкостях языка Python можно на специальных курсах от наших партнеров в Powercode и ШАГ.

Пользовательские функции разработчики приложений на Python должны создавать самостоятельно. Для этого в языке существуют специальные конструкции, которыми нужно просто научиться пользоваться. И чем лучше вы этому научитесь, тем лучше будет выглядеть ваш код. И более того, его будет проще поддерживать и дорабатывать. Пользовательские функции помогают:

  • разделить объемный код на понятные, осмысленные части;
  • вынести повторяющийся код в один блок;
  • оптимизировать скорость работы приложения.

Про встроенные функции Python в этой статье мы говорить практически не будем, но знайте, что они есть. И перед тем, как писать свою функцию, проверьте, существует ли встроенная функция, которая подходит для решения вашей задачи.

Стратегічний курс від laba: Business English для фінансистів.
Завоюйте світовий ринок.

2. Именные функции (инструкция def)

Из названия термина ясно, что синтаксис такой функции обязательно должен включать ее имя:

def function_name(parameters): """здесь можно описать, что делает функция""" statement(s) return result

Первая строка — заголовок функции. Далее следуют опциональная строковая переменная (в тройных кавычках) и тело функции (обозначено как statement(s) ).

У синтаксиса функции есть ряд особенностей:

    Заголовок функции должен начинаться с ключевого слова def .

Професійний курс від robotdreams: Алгоритми та структури даних.
Знаходьте нестандартні рішення у складних робочих задачах.

Функции Python могут иметь произвольное имя. Но желательно, чтобы имя было глаголом и отражало суть задачи, которую решает эта функция.

Пример:

def greet(name): """ Функция выводит приветственное сообщение для имени name """ print("Hello, " + name + ". Good morning!")

Напомним также общие правила именования переменных, которые полностью распространяются и на имена функций:

  1. Имя может состоять из чисел, латинских символов и символа нижнего подчеркивания и не должно включать что-либо другое.
  2. Имя функции не должно включать пробелы.
  3. В начале имени нельзя ставить цифру.
  4. X и x — это два разных идентификатора (регистр имеет значение).
  5. Имена функций рекомендуют начинать со строчной буквы.
  6. В качестве имени пользовательской функции запрещено использовать ключевые слова языка Python и имена его встроенных функций.

Вызов функции

Функцию можно вызвать из консоли Python, из скрипта или из другой функции. Чтобы сделать это для именной функции мы должны написать ее имя, а в скобках при необходимости передать ей параметры, либо оставить скобки пустыми.

>>> say_goodbye('Paul') Goodbye, Paul.

вызов функции из консоли Python

def say_goodbye(name): print("Goodbye, " + name) say_goodbye('Paul')

вызов функции say_goodbye из скрипта Python и вызов функции print из функции say_goodbye

ВАЖНО: язык Python не позволяет вызывать функцию до того, как она была создана. Потому что анализатор Python в данном случае сканирует код сверху вниз и не может найти объявление функции, которая была вызвана.

# вызов функции say_goodbye('Paul') # реализация функции def say_goodbye(name): print("Goodbye, " + name) # Ошибка: в точке say_goodbye('Paul') функция 'say_goodbye' не определена, не существует

вызов функции до ее объявления

Без вызова именная функция никогда не запустится. То есть, мы обязательно должны вызвать именную функцию, чтобы заставить работать код внутри нее, включая инструкцию return , о которой расскажем в специальном разделе.

функции и их аргументы в Python

3. Документирование функции

После заголовка функции идет опциональная строка, в которой можно написать любой текст. Но в данном случае она нужна для описания, документирования работы функции. Ее еще называют иностранным словосочетанием docstring . Вряд ли вы помните, что делает и как работает каждая функция, которую вы написали. Если даже вы это помните, то остальные разработчики, которые будут сопровождать или как-то еще использовать ваш код, не в курсе.

Поэтому такое документирование позволяет в итоге сэкономить время. А те минуты, которые вы потратите на него, окупятся с избытком.

Вспомним функцию из предыдущего примера и добавим в нее docstring :

def greet(name): """ Функция выводит приветственное сообщение для имени name """ print("Hello, " + name + ". Good morning!")

объявление функции с документированием

Все, теперь, встретившись с таким кодом, другие разработчики сразу поймут, что к чему. Понятно, что тут очень простой пример, но представьте, что это большой и запутанный код.

Но оказывается, можно сделать жизнь разработчиков еще проще. Встретив функцию, они могут не искать ее объявление по всему проекту, а воспользоваться специальным атрибутом __doc__ .

>>> print(greet.__doc__) Функция выводит приветственное сообщение для имени name

вывод значения атрибута __doc__ для функции greet

4. Аргументы функции

Вновь вернемся к заголовку функции и разберемся, какими могут быть эти самые параметры, они же — аргументы. Сколько их может быть? В предельном случае их может не быть вовсе. Тогда получаем такой заголовок:

def function_name():

и вот такой вызов функции:

function_name();

Рассмотрим теперь более распространенный случай, когда аргументов несколько.

def say_goodbye(name, msg): print("Goodbye", name + ', ' + msg) say_goodbye("Monica", "Sweet dreams!")

Функция say_goodbye принимает два аргумента — переменные name и msg . Вызывая функцию, мы передаем в нее значения, которые соответствуют аргументам. То есть эти значения (“ Monica ” и “ Sweet dreams! “) подставляются вместо переменных name и msg соответственно.

Результат работы программы:

Goodbye Monica, Sweet dreams!

Отлично. Два аргумента — два переданных значения. Все работает.

Но что будет, если мы передадим в эту же функцию только одно значение или совсем не передадим значения?

>>> say_goodbye("Monica") TypeError: say_goodbye() missing 1 required positional argument: 'msg' >>> say_goodbye() TypeError: say_goodbye() missing 2 required positional arguments: 'name' and 'msg'

Как видите программа работать не будет и выдаст ошибку для каждого вызова. Получается, Python не позволяет передавать количество значений, не совпадающее с количеством аргументов, указанных в объявлении функции?

Если отвечать в очень грубом приближении, то не позволяет. Но далее мы увидим, как можно решить эту задачу, если очень хочется.

Значения аргументов по умолчанию

Python позволяет задавать значения аргументов по умолчанию.

def say_goodbye(name, msg="Sweet dreams!"): print("Goodbye", name + ', ' + msg)

Конструкция msg=»Sweet dreams!» в первой строке означает, что при вызове функции значение аргумента msg можно не задавать. Достаточно задать только значение аргумента name , а значение msg подставится само.

И тогда программа будет работать без ошибок:

Goodbye Monica, Sweet dreams!

При этом вариант вызова с полным количеством аргументов также будет работать

say_goodbye(«Bruce», «See you!»)

и программа выдаст

Goodbye Bruce, See you!

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

Однако, в силу особенностей языка Python, мы не можем переписать код так:

def say_goodbye(msg = «Sweet dreams!», name):

Потому что получим ошибку.

SyntaxError: non-default argument follows default argument

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

Порядок передачи аргументов

При вызове функции нельзя просто так поменять местами значения, которые вы передаете в качестве аргументов.

say_goodbye(«See you!», «Bruce»)

приведет к следующему результату:

Goodbye See you!, Bruce

Потому что в объявлении функции аргументы расположены не в том порядке:

def say_goodbye(name, msg):

В Python такие аргументы называются позиционными. Но существуют и аргументы другого типа — именованные или ключевые (калька с английского keyword arguments ). Если точнее, то существует другой способ передачи значений аргументов при вызове функции.

# 2 ключевые аргументы say_goodbye(name = "Bruce", msg = "See you!") # 2 ключевые аргументы в другом порядке say_goodbye(msg = "See you!",name = "Bruce")

Такая конструкция позволяет игнорировать порядок передачи аргументов при вызове функции. Хотя можно использовать и смешанный вариант:

# позиционный и ключевой аргумент say_goodbye("Bruce", msg = "See you!")

Функции с неизвестным количеством аргументов

Если мы не знаем, сколько значений будет обрабатывать функция, можно задать ее аргументы в виде списка.

def say_goodbye(*names): """Функция выведет приветствие для каждого имени из полученного names""" for name in names: print("Goodbye", name)

В этом случае перед именем списка пишется знак * . Тут names — это список имен неизвестной длины. Функция обрабатывает его, как обычный список.

Вызывая эту функцию, мы можем в качестве аргументов передавать произвольное количество значений. Они преобразуются в список и полученный список автоматически подставляется вместо переменной names.

say_goodbye(«Monica», «Luke», «Steve», «John»)

Результат работы программы:

Goodbye Monica Goodbye Luke Goodbye Steve Goodbye John

5. Инструкция return

Несмотря на то, что эта инструкция опциональная, она помогает в двух случаях:

  • Когда нужно вернуть результат работы функции в виде значения, которое может использовано вне функции — например, записано во внешнюю переменную.
def sum(a,b): return a+b
  • Когда нужно прервать работу функции и вернуться к той точке программы, из которой была вызвана эта функция.
def division(a,d): if d == 0: # если делитель равен нулю return "Нельзя делить на ноль" # мы прерываем работу функции return a / d

Посмотрим, как будут работать эти функции с различными значениями аргументов.

print(sum(2, 4)) print(sum(2, -4))
6 -2 print(division(4, 2)) print(division(4, 0))
2.0 Нельзя делить на ноль

Если в коде функции нет инструкции return , она не возвращает ничего. Запустив в консоли функцию из предыдущего раздела, в третьей строке мы получим None .

>>> print(say_goodbye("May")) Goodbye, May. None

6. Глобальные и локальные переменные

В этой статье мы еще не встречали функции, в которых помимо аргументов использованы переменные. Например:

def multiplicator(x): k = 2 return k * x

Что это за переменная k ?

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

В приведенном выше примере переменная k видна только внутри функции. В этом случае говорят, что переменная является локальной.

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

Локальные переменные обычно живут до тех пор, пока функция не завершит свою работу после очередного вызова. Во время каждого вызова функции все ее локальные переменные сбрасываются и инициализируются заново. Значения (если они были изменены) локальных переменных из предыдущих вызовов функция не хранит.

Хорошо, тогда что будет, если создать переменную с тем же именем, но за пределами функции?

def multiplicator(x): k = 2 print("Значение локальной переменной k:", k) return k*x k = 20 multiplicator(4) print("Значение внешней переменной k:", k)
Значение локальной переменной k: 2 Значение внешней переменной k: 20

В этом примере внешняя переменная k никак не влияет на результат работы функции. Дело в том, что сначала функция ищет переменную с подходящим именем внутри своей локальной области видимости — где как раз находится локальная переменная k .

функции и их аргументы в Python

Если мы удалим эту переменную из реализации функции, то она будет искать k уже во внешних по отношению к ней блоках кода (пошагово двигаясь изнутри наружу). В данном случае она найдет внешнюю переменную k , равную 20 и использует ее значение для своих вычислений.

Но если нам нужно не просто использовать, а еще и модифицировать это значение, необходимо внести изменения в код:

def multiplicator(x): global k k = 2 print("Значение локальной переменной k:", k) return k*x k = 20 multiplicator(4) print("Значение внешней переменной k:", k)

Добавив выделенные жирными строки ( global k и k = 2 ), мы сообщаем анализатору Python, что не намерены создавать локальную переменную k : мы просто модифицируем глобальную переменную.

Язык программирования Python – один из самых востребованных. С каждым годом потребность в специалистах с его знаниями только растет. Поэтому если вам он интересен, то вы можете записаться на курс к нашим друзьям из академии ШАГ или Mate Academy. Получите высокооплачиваемую профессию на долгие годы.

7. Рекурсивные функции

В разделе про python def function мы упоминали, что функцию можно вызывать, находясь внутри другой функции. Оказывается, функция может вызывать саму себя внутри своего же исходного кода.

def factorial(x): #условие окончания рекурсии if x == 1: return 1 else: return (x * factorial(x-1)) num = 3 print("Факториал числа", num, "равен", factorial(num))

Такие функции называют рекурсивными. В данном случае factorial(x) один раз вызывается из внешней программы и два раза — из самой себя. Перед каждым из двух этих вызовов значение аргумента x уменьшается на 1. Это происходит до тех пор, пока x не достигнет значения, равного 1. Это так называемое условие окончания рекурсии.

Программа отработает и выведет соответствующее сообщение:

Факториал числа 3 равен 6

Последовательность вычислений можно представить в хронологическом порядке:

Операция Значение x Состояние программы Условие окончания рекурсии
factorial(3) 3 первый вызов функции не выполнено
3 * factorial(2) 2 второй вызов, погружение в рекурсию не выполнено
3 * (2 * factorial(1)) 1 третий вызов, погружение в рекурсию не выполнено
3 * (2 * 1) 1 выход из рекурсии (всплываем) выполнено
return 3 * 2 2 выход из рекурсии выполнено
6 3 возвращение результата выполнено

8. Анонимные функции (инструкция lambda)

Их также называют лямбда-функциями (это отсылка к математическому инструментарию под названием Лямбда Исчисление). Ключевое отличие анонимных от именных функций, казалось бы, заложено в их названиях. Но это не совсем так.

Во-первых, синтаксис функций отличается кардинально:

lambda аргументы: выражение

Во-вторых, лямбда-функция может выполнить только одну инструкцию (действие).

Для чего тогда нам нужны такие узкоспециализированные функции?

Анонимные функции идеально подходят, если нужно передать функцию в другую функцию в качестве аргумента. И если больше нигде переданная функция не будет вызвана — имя ей не понадобится. Ну и требование выполнять только одно действие (вычислять лишь одно выражение) здесь тоже играет в плюс, так как делает код более лаконичным.

l = [2, 5, 1, 4] l.sort(key=lambda x: x)
l = [2, 5, 1, 4] l.sort(key=lambda x: -x)

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

Важно также отметить, что лямбда-функции не используют инструкцию return , но всегда возвращают результат. В одном из наших примеров это результат вычисления выражения -x .

9. Присвоение функции переменной

Присвоение анонимной функции

Будет очень в тему еще один пример с анонимной функцией:

double = lambda x: x * 2

В данном случае мы просто присвоили имя этой лямбда-функции, но не вызвали ее. Этот код эквивалентен вот такой реализации именной функции:

def double(x): print(x * 2) return x * 2

Теперь для вызова нашей анонимной функции, записанной в переменную double , нужно добавить ей скобки, подставив произвольное значение аргумента. Например:

Присвоение именной функции

Хорошо, а какие чудеса мы сможем сотворить, если запишем в переменную именную функцию? Для примера создадим вот такую функцию:

def f(): print("I am f")

Зададимся целью ввести такую переменную g , чтобы

  • g() запускал вызов функции f
  • с печатью строки I am f

Первый способ

def f(): print("I am f") # присваивание g = f # вызов функции g()

Это работает, потому что благодаря присваиванию переменная g указывает на тот же участок памяти (блок кода), что и функция f . А значит, подставив к g скобки, мы получим обычный вызов функции.

Второй способ

Используем так называемую лямбда-обертку. Создадим лямбда-функцию без аргументов, с возвращаемым значением в виде f() и запишем ее в переменную g (примерно так мы делали в начале раздела).

def f(): print("I am f") # лямбда-обертка g = lambda : f() # вызов функции g()

Это будет работать так же, так как лямбда-функция, записанная в переменную g запустится (то есть отправит на выполнение инструкцию f() ) только после выполнения инструкции g()

Заключение

Функции Python — это достаточно гибкий механизм, но в нем легко запутаться, не зная тонкостей. Надеюсь, в этой статье нам удалось заложить основы и объяснить важные детали при работе с функциями. Но если у вас остались вопросы, или вы хотите более подробно вникнуть в язык программирования Python, то курсы наших друзей Hillel и Powercode, помогут вам освоить новые знания.

Видео: примеры использования функции map()

Какой порядок вычисления в Python?

Всем привет!
Есть такое выражение:
10 — 2 + 3 — 6 = ?

Пишут, что порядок вычислений в Python такой:
1. Выражение в скобках;
2. Экспоненты;
3. Умножение;
4. Деление;
5. Сложение;
6. Вычитание.

Т.е. сначала идет сложение, а потом вычитание. Значит, ответом на выражение в начале текста должность быть «-1».
Однако, Python выдает «5».
Как так? О.о
Python просто вычисляет по порядку слева направо?

Пробовал в Jupiter Notebook и Wing101

  • Вопрос задан более трёх лет назад
  • 3709 просмотров

6 комментариев

Простой 6 комментариев

Swartex

простите, где скобки?
в данном примере слева на право

Всё правильно вычисляет, скобок то нет. Сложение и вычитание имеют одинаковый приоритет, что первое стоит, то и вычисляется.

Вы математикой уровня начальной школы не владеете. Какой вам python?

kshnkvn

Может кто гайд дать что нужно делать с этими числами, что-бы получить -1?
Ivan Yakushenko, Все очень просто:
Т.к.

сначала идет сложение, а потом вычитание.

2 + 3 = 5 (да, да, даже не -2 + 3, а 2 + 3). 10 — 5 = 5; 5 — 6 = -1.

kshnkvn

D3lphi, ***се, вот это математика.
Решения вопроса 0
Ответы на вопрос 3

Vlatqa

Т.е. сначала идет сложение, а потом вычитание. Значит, ответом на выражение в начале текста должность быть «-1».

10 + 3 = 13
13 — 2 = 11
11 — 6 = 5
а как у тебя получилось -1?
Ответ написан более трёх лет назад
Нравится 1 4 комментария
Евгений @ezhestovskiy Автор вопроса
10 — 2 + 3 — 6 = 10 — 5 — 6 = -1
2 + 3 = 5
10 — 5 = 5
5 — 6 = -1
MechanicZelenyy @MechanicZelenyy

Евгений, вы как-то неправильно прочитали гайд, может забыли про унарные операторы, но результат должен совпадать с математическим.

Евгений, — 2 + 3 = 1 у вас математика страдает. 10 — 2 + 3 — 6 = 10 + 1 — 6 = 5
Евгений @ezhestovskiy Автор вопроса
tuwkan, Ага, теперь разобрался, спасибо!

chupasaurus

chupasaurus @chupasaurus
Сею рефлекторное, злое, временное

Поскольку вычитание является сложением с отрицательным числом, перестановки слагаемых не меняют значение.
Интерпретатор считает ваше выражение как 10 + 3 — 2 — 6.

Ответ написан более трёх лет назад
Евгений @ezhestovskiy Автор вопроса
Спасибо. Такого не знал.

JaxxDexx

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

>>> def f(): . a = 10 . b = 2 . c = 3 . d = 6 . e = a - b + c - d . >>> from dis import dis >>> dis(f) 2 0 LOAD_CONST 1 (10) 2 STORE_FAST 0 (a) 3 4 LOAD_CONST 2 (2) 6 STORE_FAST 1 (b) 4 8 LOAD_CONST 3 (3) 10 STORE_FAST 2 (c) 5 12 LOAD_CONST 4 (6) 14 STORE_FAST 3 (d) 6 16 LOAD_FAST 0 (a) 18 LOAD_FAST 1 (b) 20 BINARY_SUBTRACT 22 LOAD_FAST 2 (c) 24 BINARY_ADD 26 LOAD_FAST 3 (d) 28 BINARY_SUBTRACT 30 STORE_FAST 4 (e) 32 LOAD_CONST 0 (None) 34 RETURN_VALUE

А вот умножение/деление более приотитетные и выполняются раньше:

>>> def f2(): . a = 10 . b = 3 . c = 5 . d = 6 . e = a + b / c * d . >>> dis(f2) 2 0 LOAD_CONST 1 (10) 2 STORE_FAST 0 (a) 3 4 LOAD_CONST 2 (3) 6 STORE_FAST 1 (b) 4 8 LOAD_CONST 3 (5) 10 STORE_FAST 2 (c) 5 12 LOAD_CONST 4 (6) 14 STORE_FAST 3 (d) 6 16 LOAD_FAST 0 (a) 18 LOAD_FAST 1 (b) 20 LOAD_FAST 2 (c) 22 BINARY_TRUE_DIVIDE 24 LOAD_FAST 3 (d) 26 BINARY_MULTIPLY 28 BINARY_ADD 30 STORE_FAST 4 (e) 32 LOAD_CONST 0 (None) 34 RETURN_VALUE

3.1. Теория¶

Практически любая программа получает на вход какие-либо данные, обрабатывает их и генерирует выходную информацию. Для этого типизированный язык программирования должен знать, с какими данными он имеет дело и какие операции над ними можно производить.

3.1.1. Понятие типа данных и переменной¶

Тип данных (англ. Data type) — характеристика, определяющая:

  • множество допустимых значений, которые могут принимать данные, принадлежащие к этому типу (например, объект типа Целое число может принимать только целочисленные значения в определенном диапазоне);
  • набор операций, которые можно осуществлять над данными, принадлежащими к этому типу (например, объекты типа Целое число умеют складываться, умножаться и т.д.).

Все типы в Python являются объектами (в отличие, например, от C++). При создании объекта вызывается специальная функция — конструктор.

Переменная (англ. Variable) — это идентификатор, который указывает на определенную область памяти, где хранятся произвольные данные — созданный объект (значение переменной).

Для имен переменных используется змеиный_регистр (англ. snake_case): например, my_variable или i .

Информативные имена переменных.

Переменным необходимо давать информативные имена, по которым можно было бы понять, с какими данными она связана — это чрезвычайно облегчает дальнейшее чтение и изменение кода.

Например, переменную, хранящую данные о скорости можно назвать speed , а не sk ; значение баланса телефона клиента — balance , а не b и т.д. «Привычные» со школы короткие имена следует использовать там, где они либо подходят по смыслу (например, a , b , c в роли коэффициентов квадратного уравнения), либо используются временно (например, счетчик i в циклической конструкции).

3.1.1.1. Классификация типов данных¶

В Python встроенные типы данных подразделяются на 2 группы:

  1. Числа (целое, вещественное).
  2. Логический тип.
  3. NoneType.
  1. Последовательности: строка, список, кортеж, числовой диапазон.
  2. Множества.
  3. Отображения: словарь.

Кроме того, все объекты в Python относятся к одной из 2-х категорий:

  1. Мутирующие (англ. Mutable): содержимое объекта можно изменить после создания (например, список);
  2. Немутирующие (англ. Immutable): содержимое объекта нельзя изменить после создания (например, строка или число).

Также часто используется терминология «изменяемые» и «неизменяемые» типы соответственно.

Как мутирующие, так и немутирующие объекты имеют свои преимущества и недостатки. Основным преимуществом немутирующих типов является гарантия неизменяемости с момента создания: каждый использующий участок кода имеет дело с копией объекта и не может его каким-либо образом изменить. Этот же принцип формирует основной недостаток немутирующих типов: большее количество потребляемой памяти на дополнительное копирование объектов при необходимости внесения изменений.

3.1.1.2. Оператор присваивания¶

Для связывания (и при необходимости предварительного создания) объекта и переменной используется оператор присваивания = .

Присваивание выполняется «справа налево» и подразумевает шаги:

    если справа от оператора находится литерал (например, строка или число) в операнд слева записывается ссылка, которая указывает на объект в памяти, хранящий значение литерала:

a = 100 # Создание объекта 100 и запись ссылки на него в переменную 'a' 
a = 100 b = a # В переменную 'b' копируется ссылка из 'a' - # они будут указывать на один и тот же объект 

Переменная лишь указывает на данные — хранит ссылку, а не сами данные. В виду того, что копирования данных при этом не происходит, операция присваивания выполняется с высокой скоростью.

В связи с этим целесообразнее в Python в качестве метафоры рассматривать переменные как стикеры (этикетки), цепляемые к данным, а не ящики (Рисунок 3.1.1) и говорить, что «переменная присвоена объекту», а не привычное «переменной присвоен объект».

_images/03_01_01.png

Рисунок 3.1.1 — Переменные в Python — стикеры, а не ящики 3 ¶

Пример использования оператора присваивания приведен в Листинге 3.1.1.

Листинг 3.1.1 — Оператор присваивания в Python ¶

# Выражение присваивания в Python может быть записано несколькими способами в # зависимости от содержимого левой части (l-значение) и правой части (r-значение). # 1. Простое присваивание использует одно l-значение и одно r-значение. # # Объект 5 целого типа связывается с переменной 'a' >>> a = 5 >>> a 5 # 2. Сокращенная запись присваивания часто применяется когда нужно обновить # значение переменной по отношению к текущему значению. # Сокращенная запись образуется для всех операторов одинаково, например # '*=' для умножения и т.д. # # Увеличиваем значение связанного целого объекта 'a' на 1, эквивалентно a = a + 1 >>> a += 1 >>> a 6 # 3. Также возможно параллельное присваивание, где выражение присваивания # содержит больше одного l- и r-значений. # # Связывание значений 1, "aaa", 3 с переменными 'x', 'y', 'z' соответственно >>> x, y, z = 1, "aaa", 3 >>> x, y, z (1, 'aaa', 3) # Возможно также не совпадения количества значения l- и r-значений, # данный случай рекомендуется рассмотреть самостоятельно. # 4. Оператор присваивание выполняется справа налево, поэтому также можно # образовывать цепочки присваивания. # # 0 связывается с переменной 'y', а затем и с переменной 'x' >>> x = y = 0 >>> x, y (0, 0) 

Инициализация переменной перед использованием

Переменная должна быть проинициализирована (ссылаться на данные) перед использованием в выражении. Например, код a = b + 2 или b += 1 , вызовет ошибку, если идентификатор b не был предварительно определен.

Присваивание и побочный эффект

Присваивание, меняя значение переменной, изменяет состояние программы — т.е. имеет побочный эффект. После выполнения присваивания, например x += 1 , весь дальнейший код программы будет иметь дело с новым, измененным значением 1.

3.1.1.3. Управление памятью и сборщик мусора¶

Создание объекта любого типа подразумевает выделение памяти для размещения данных об этом объекте. Когда объект больше не нужен — его необходимо удалить, очистив занимаемую память. Python — язык с встроенным менеджером управления памятью и выполняет данные операции автоматически за счет наличия сборщика мусора (англ. Garbage Collection, GC).

Сборка мусора — технология, позволяющая, с одной стороны, упростить программирование, избавив программиста от необходимости вручную удалять объекты, созданные в динамической памяти, с другой — устранить ошибки, вызванные неправильным ручным управлением памятью. Алгоритм, используемый сборщиком мусора называется подсчетом ссылок (англ. Reference Counting). Python хранит журнал ссылок на каждый объект и автоматически уничтожает объект, как только на него больше нет ссылок (Рисунок 3.1.2).

Рисунок 3.1.2 — Примерная схема работы сборщика мусора ¶

Время между созданием и уничтожением объекта — его жизненный цикл.

Объекты, которые имеют на протяжении своего жизненного цикла одно неменяющееся и характеризующее их значение, а также умеют сравниваться, называются хешируемыми. К хешируемым объектам относятся все немутирующие типы данных, а также пользовательские объекты.

3.1.2. Скалярные типы¶

3.1.2.1. Числа¶

В Python существует 2 категории чисел: целые и вещественные (с плавающей точкой).

3.1.2.1.1. Целое число¶

Целые числа в Python представлены типом int .

Размер целого числа ограничивается только объемом памяти компьютера. Литералы целых чисел по умолчанию записываются в десятичной системе счисления, но при желании можно использовать и другие (Листинг 3.1.2).

Листинг 3.1.2 — Пример литералов целых чисел ¶

>>> 15 # десятичное число 15 >>> 0b1111 # двоичное число 15 >>> 0o17 # восьмеричное число 15 >>> 0xF # шестнадцатиричное число 15 
3.1.2.1.2. Вещественное число¶

Python предоставляет три типа значений с плавающей точкой:

  • float (двойная точность)
  • complex (комплексные числа вида 3.5 + 5j );
  • decimal.Decimal (большая точность, по умолчанию 28 знаков после запятой).

Наиболее часто используемый тип float представляет числа с плавающей точкой двойной точности, диапазон значений которых зависит от компилятора, применявшегося для компиляции интерпретатора Python. Числа типа float записываются с десятичной точкой или в экспоненциальной форме записи (Листинг 3.1.3).

Листинг 3.1.3 — Пример литералов вещественных чисел ¶

>>> 5.7 # Точка - разделитель целой и дробной части 5.7 >>> 4. # Если дробной части нет, ее можно опустить 4.0 >>> -2.5 # Отрицательное вещественное число -2.5 >>> 8e-4 # Экспоненциальная форма записи 0.0008 >>> 0.1 + 0.2 # Проблема потери точности актуальна для вещественных чисел 0.30000000000000004 

Для чисел с плавающей точкой существует ряд нюансов:

  • в машинном представлении такие хранятся как двоичные числа. Это означает, что одни дробные значения могут быть представлены точно (такие как 0.5 ), а другие — только приблизительно (такие как 0.1 и 0.2 , например, их сумма будет равна не 0.3 , а 0.30000000000000004 );
  • для представления используется фиксированное число битов, поэтому существует ограничение на количество цифр в представлении таких чисел.

В связи с этим числа типа float не могут надежно сравниваться на равенство значений, т.к. имеют ограниченную точность. Проблема потери точности — это не проблема, свойственная только языку Python, а особенность компьютерного представления чисел 2.

3.1.2.1.3. Операции над числами¶

Типовые операции, которые можно производить над числами ( int и float ), указаны в Листинге 3.1.4.

Для арифметических операций тип результата операции определяется типом аргументов. Если тип результата явно не предусмотрен при вычислении (например, округление до целых подразумевает получение результата типа int ), действуют следующие правила:

  • float : если хотя бы один аргумент имеет тип float ;
  • int : если все аргументы имеют тип int .

Листинг 3.1.4 — Операции над числами в Python ¶

# 1. Арифметические операции # Тип результата операции определяется типом аргументов # -х # Меняет знак х на обратный >>> x = 5 >>> -x -5 # х + у, х - у, х * у # Сложение, разность, произведение чисел х и у >>> 5 + 3 8 >>> 5 - 7 -2 >>> 5 * 3 15 # х / у # Делит х на у (результат типа float) >>> 5 / 3 1.6666666666666667 # x // y # Делит х на у нацело - усекает дробную часть (результат типа int) >>> 5 // 3 1 # х % у # Возвращает модуль (остаток) от деления х на у >>> 5 % 3 2 # x**y # Возводит х в степень у >>> 5**3 125 # abs(x) # Возвращает абсолютное значение х >>> abs(-5) 5 # round(x, n) # Возвращает значение x, округленное до n знаков после запятой; # тип результата зависит от n (int, если n равно 0, при этом его можно не указывать) >>> round(4/3, 2) 1.33 >>> round(4/3) 1 # 2. Равенство и сравнение # Результат логического типа # x == y, x != y # Проверка чисел на равенство/неравенство >>> 5 == 4 False >>> 5 != 4 True # x > y, x < y, x >= y, x # Больше, меньше, больше или равно, меньше или равно >>> 5 > 4 True >>> 5  5 True # Возможно составление цепочек сравнений >>> 3  4  5 True 

3.1.2.2. Логический тип¶

Логический тип представлен типом bool :

и позволяет хранить 2 значения:

  • True (Истина / Да / 1);
  • False (Ложь / Нет / 0).

Операции, которые можно производить над объектами логического типа, указаны в Листинге 3.1.5.

Листинг 3.1.5 — Операции над объектами логического типа в Python ¶

>>> x = True >>> y = False >>> not x False >>> x and y False >>> x or y True # Python использует "ленивую" модель вычисления: если на каком-то # этапе результат выражения известен, оно не вычисляется до конца >>> (4 > 5) and (5 > 2) False 

Правила выполнения операций соответствует логическим таблицам истинности.

3.1.2.3. NoneType¶

В Python существует специальное значение None типа NoneType, обозначающее нейтральное или «нулевое» поведение. Присвоение такого значения ничем не отличается от других: a = None , обозначая, что идентификатор a задан, но ни с чем не связан.

Наиболее часто используется для защитного программирования — «если что-то не None, можно продолжать работу программы».

3.1.3. Коллекции¶

Используя скалярные типы, можно столкнуться с проблемой — что делать, если необходимо хранить и обрабатывать набор таких значений. Для этого в Python предназначены специальные типы — коллекции.

Коллекции — это группа типов данных, которые содержат в себе другие данные и поддерживают:

  • проверку на вхождения элементов in и not in ( True / False );
  • определение размера len() ;
  • возможность выполнения итераций (перемещения по элементам последовательности) — из-за этого коллекции также называются итерируемыми объектами (подробнее рассматриваются в Теме №4 ).

Среди коллекций выделяют 3 группы:

  • последовательности: строка, список, кортеж, числовой диапазон;
  • множества;
  • отображения: словарь.

3.1.3.1. Последовательности¶

Последовательность — это упорядоченная коллекция, поддерживающая индексированный доступ к элементам.

Некоторые последовательности в Python в отличие от традиционных массивов (например, в Паскале или Си) могут хранить элементы различного типа (в том числе и коллекции различных видов).

В языке Python имеется пять встроенных типов последовательностей (Таблица 3.1.1).

Далее подробно рассматриваются объекты str , list , tuple и range .

3.1.3.1.1. Общие операции¶

Некоторые операции справедливы для всех последовательностей (за исключением случаев, где они не возможны исходя из определения типа).

Ниже используются следующие обозначения:

  • s и t : последовательности одного типа;
  • n , k , start , end , step : целые числа;
  • x : произвольный объект, отвечающий критериям соответствующего вызова функции.

Функция len() возвращает длину (количество элементов в последовательности) s .

Конкатенация («склеивание») s + t

Возвращает новый объект — «склейку» s и t .

Дублирование s * n n * s

Возвращает последовательность, повторяющуюся n раз.

Индексация и срезы

Получить доступ к отдельному элементу или группе элементов последовательности возможно с помощью оператора [] . Индексацию (получение отдельного элемента) можно считать частным случаем получения среза (слайсинга).

Оператор получения среза имеет три формы записи:

  • s[start] : индексация (с 0);
  • s[start:end] : срез [start; end) ;
  • s[start:end:step] : срез [start; end) c шагом step .

В ряде случаев целочисленные параметры start , end и step могут быть опущены. Элемент с индексом end не включается в результат при взятии срезов.

Минимальное и максимальное значения min ( s ) ¶ max ( s ) ¶

Возвращает минимальный и максимальный элементы последовательности s соответственно.

Проверка на вхождение x in s

Возвращает True , если x входит в последовательность s и False в противном случае.

Индекс (положение) элемента s.index(x[, start[, end]]) —> int

Возвращает первое вхождение элемента x в последовательность s (между индексами start и end , если они заданы).

Количество повторений s. count ( x ) ¶

Возвращает количество вхождений элементов x в последовательность s .

Сортировка sorted ( s , key = None , reverse = False ) ¶

Возвращает отсортированный объект в виде списка. Исходный объект при этом не изменяется.

  • key – функция сортировки (по умолчанию не учитывается, сортировка осуществляется поэлементно);
  • reverse – если равен True , сортировка осуществляется в обратном порядке.

В Листинге 3.1.6 приведен пример выполнения указанных операций на примере последовательности «Список». Выполнение срезов отдельно рассматривается на примере строк ниже.

Листинг 3.1.6 — Общие операции для последовательностей ¶

>>> s = [1, 2, 3] # Список из 3-х целых чисел >>> len(s) 3 >>> 1 in s True >>> 5 in s False >>> s += [5, 6] >>> s [1, 2, 3, 5, 6] >>> s *= 2 >>> s [1, 2, 3, 5, 6, 1, 2, 3, 5, 6] >>> min(s), max(s) (1, 6) >>> s.index(5) 3 >>> s.count(4) 0 >>> sorted(s) [1, 1, 2, 2, 3, 3, 5, 5, 6, 6] 
3.1.3.1.2. Строка¶

Строка ( str ) — это упорядоченная неизменяемая последовательность символов Юникода.

class str ( object = » ) ¶ class str ( object = b» , encoding = ‘utf-8’ , errors = ‘strict’ )

Литералы строк создаются с использованием кавычек или апострофов, при этом важно, чтобы с обоих концов литерала использовались кавычки одного и того же типа. Также можно использовать строки в тройных кавычках, то есть строки, которые начинаются и заканчиваются тремя символами кавычки (либо тремя кавычками, либо тремя апострофами).

Важным для строкового типа является понятие кодировки символов, что в частности, влияет на правила сравнения строк. По умолчанию Python хранит строки в кодировке UTF-8.

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

Таблица 3.1.2 — Экранированные последовательности в Python ¶

Символ «Перевод строки»

Пример создания строковых литералов приведен в Листинге 3.1.7, базовые операции — в Листинге 3.1.8.

Листинг 3.1.7 — Создание строк ¶

# Запись строковых литералов "Простой текст в кавычках" 'Текст в апострофах' """А это текст, который занимает 2 строки (в данном случае использовать три апострофа не рекомендуется)""" # Экранированные последовательности начинаются с символа \ "Текст, который содержит \"текст в кавычках\"" 'Текст, который содержит \'текст в апострофах\'' "Если внутри кавычки другого типа, можно не 'экранировать'" "Так в строке будет табуляция\tи\nперенос, а также обратный слеш \\" # "Отключить" экранирование можно указав, что строка является "сырой" r"Так в строке не будет табуляция\tи\nпереноса, но будет 2 обратных слеша \\" 

Листинг 3.1.8 — Операции над строковым типом ¶

# 1. Арифметические операции # Тип результата операции определяется типом аргументов # s1 + s2 # Соединяет строки s1 и s2 >>> "Py" + "thon" 'Python' # или просто написать рядом >>> "Py" "thon" 'Python' # s1 * n # Составляет строку из n повторений строки s1 >>> "па" * 2 'папа' # 2. Равенство и сравнение # Результат логического типа # # Операции сравнения выполняются посимвольно слева направо с учетом кодировки. # Ознакомиться с таблицей символов Юникода рекомендуется на ресурсе # http://unicode-table.com/. # s1 == s2, s1 != s2 # Проверка строк на равенство/неравенство >>> "текст1" == "текст2" False >>> "текст1" != "текст2" True # x > y, x < y, x >= y, x # Больше, меньше, больше или равно, меньше или равно >>> "текст1" > "текст2" False >>> "текст1"  "текст2" True # Возможно составление цепочек сравнений >>> "текст1"  "текст12"  "текст2" True # s1 in s2 # Проверка вхождения строки s1 в s2 >>> "p" in "Python" False 

Пример доступа к отдельному символу и получения срезов приведен в Листинге 3.1.9.

Листинг 3.1.9 — Индексация и срезы ¶

# Для индексации и получения срезов удобно пользоваться обозначениями ниже # # Индексация # +---+---+---+---+---+---+ # | P | y | t | h | o | n | # +---+---+---+---+---+---+ # 0 1 2 3 4 5 # -6 -5 -4 -3 -2 -1 # # Срезы # +---+---+---+---+---+---+ # | P | y | t | h | o | n | # +---+---+---+---+---+---+ # 0 1 2 3 4 5 6 # -6 -5 -4 -3 -2 -1 >>> s = "Python" >>> s[0] 'P' >>> s[3] 'h' >>> s[-1] # Последний символ 'n' >>> s[0:2] # Срез включает первые 2 символа 'Py' >>> s[2:-1] # С 3 по предпоследний символ 'tho' >>> s[0:-1:2] # С 1 по предпоследний символ через 2 'Pto' # Параметры [start] и [end] могут быть опущены # В таком случае срез берется с начала и до конца строки соответственно >>> s[:3] # Первые 3 символа 'Pyt' >>> s[3:] # С 3-го символа до конца 'hon' >>> 
3.1.3.1.2.1. Характерные операции¶

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

Возвращает символ № i из таблицы Unicode.

Возвращает номер символа c из таблицы Unicode.

Пусть s — строка, на которой вызывается метод.

Возвращает копию строки s в верхнем регистре.

Возвращает копию строки s в нижнем регистре.

Возвращает копию строки с первым символом в верхнем регистре.

Возвращает копию строки, в которой первые символы каждого слова преобразованы в верхний регистр, а все остальные — в нижний регистр.

Возвращает число вхождений строки t в строку s (или в срез s[start:end] ).

Возвращает позицию самого первого (крайнего слева) вхождения подстроки t в строку s (или в срез s[start:end] ); если подстрока t не найдена, возвращается -1 .

Аналогично str.find() , но генерируется исключение ValueError , если подстрока не найдена.

Возвращает копию строки s , в которой каждое (но не более count , если этот аргумент определен) вхождение подстроки old замещается подстрокой new .

split ( sep = None , maxsplit = — 1 ) ¶

Возвращает список строк, разбитых по строке sep .

Возвращает строку-«склейку» элементов seq , используя s в качестве разделителя.

Пример использования строковых методов приведен в Листинге 3.1.10.

Листинг 3.1.10 — Использование строковых методов ¶

>>> s = "ЭТО просТо ТеКст" >>> ord(s[0]) 1069 >>> chr(1069) 'Э' >>> s.upper(), s.lower(), s.title(), s.capitalize() ('ЭТО ПРОСТО ТЕКСТ', 'это просто текст', 'Это Просто Текст', 'Это просто текст') >>> s.find("Т") 1 >>> s.replace("Т", "т") 'ЭтО просто теКст' >>> lst = s.split() >>> lst ['ЭТО', 'просТо', 'ТеКст'] >>> "-".join(lst) 'ЭТО-просТо-ТеКст' 
3.1.3.1.2.2. Форматирование строк¶

Строковый тип в Python содержит специальный метод str.format() , который позволяет удобно формировать строку из комбинации значений различного типа.

Пусть s — строка, на которой вызывается метод.

Возвращает отформатированную строку по заданному шаблону.

Строка s может содержать фигурные скобки <> (заполнители), указывающие, что их необходимо заменить на какое-либо значение. Заполнитель может содержать индекс или ключевое слово — в противном случае замена будет производится слева направо.

Пример использования метода str.format() приведен в Листинге 3.1.11.

Листинг 3.1.11 — Форматирование строк ¶

>>> age = 20 >>> name = "Максим" # 1. Без указания индексов подстановки >>> "Меня зовут <>, мне <> лет.".format(name, age) 'Меня зовут Максим, мне 20 лет.' # 2. Указание индексов подстановки (их можно и повторять!) >>> "Меня зовут , мне  лет.".format(name, age) 'Меня зовут Максим, мне 20 лет.' # 3. Именованные аргументы >>> "  ходит на  каждую пятницу".\ . format(subject="Мат. анализ", name="Иван") 'Иван ходит на Мат. анализ каждую пятницу' # 4. Интерполяция (f-string, начиная с Python 3.6) >>> f"name> ходит на subject> каждую пятницу" 'Иван ходит на Мат. анализ каждую пятницу' # 5. Модификаторы позволяют дополнительно указывать тип или формат выводимых данных # 5.1. Вывод вещественного числа с 2-мя знаками после запятой >>> "За 1 рубль дают $ ".format(1/70) 'За 1 рубль дают $0.01' # 5.2. Или вывод большого числа с "тысячными разделителями" >>> "Стоимость автомобиля:  руб.".format(5300500) 'Стоимость автомобиля: 5,300,500 руб.' 

Метод str.format обладает широкими возможностями. Дополнительно ознакомьтесь с официальной документацией по «мини-языку» форматирования.

3.1.3.1.3. Список¶

Список ( list ) — это упорядоченная изменяемая последовательность элементов.

  • может содержать элементы разного типа;
  • поддерживает операторы сравнения: при этом сравнивание производится поэлементно (и рекурсивно, при наличии вложенных элементов).

Создать список можно несколькими способами (Листинг 3.1.12).

Листинг 3.1.12 — Создание списка ¶

# 1. Пустой список создается с помощью пустых квадратных скобок или функции list() >>> [] [] >>> list() [] # 2. Инициализировать список элементами можно одним из следующих способов: >>> [1, "text", 2.0] [1, 'text', 2.0] >>> list("text") ['t', 'e', 'x', 't'] 
3.1.3.1.3.1. Характерные операции¶

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

Пусть lst — список, на котором вызывается метод.

Добавляет элемент x в конец списка lst .

extend ( m ) ¶ lst += m

Добавляет в конец списка lst все элементы коллекции m .

Вставляет элемент х в список lst в позицию i .

Удаляет из списка lst первый элемент со значением x .

Возвращает последний или i -й элемент, удаляя его из последовательности.

Удаляет из списка lst все элементы (очищает список).

sort ( lst , key = None , reverse = None ) ¶

Выполняет сортировку списка lst . Отличается от функции sorted() тем, что сортирует исходный объект, а не возвращает новый.

  • key – функция сортировки (по умолчанию не учитывается, сортировка осуществляется поэлементно);
  • reverse – если равен True , сортировка осуществляется в обратном порядке.

Переворачивает элементы списка lst .

Удаляет из списка lst элемент с индексом i (или несколько элементов, если задан индекс j ).

В Листинге 3.1.13 приведен пример использования методов списков.

Листинг 3.1.13 — Работа со списками ¶

# 1. Методы списка >>> a = [8, 7, 5.5, 1000, 3.50, 200] >>> a[0] = 7 >>> a [7, 7, 5.5, 1000, 3.50, 200] >>> a.index(7) 0 >>> a.count(7) 2 >>> a.insert(2, 1000) >>> a [7, 7, 1000, 5.5, 1000, 3.5, 200] >>> a.append(5.5) >>> a [7, 7, 1000, 5.5, 1000, 3.5, 200, 5.5] >>> a += [0, 0] >>> a [7, 7, 1000, 5.5, 1000, 3.5, 200, 5.5, 0, 0] >>> b = a.pop() >>> b 0 >>> a [7, 7, 1000, 5.5, 1000, 3.5, 200, 5.5, 0] >>> a.sort() >>> a [0, 3.5, 5.5, 5.5, 7, 7, 200, 1000, 1000] >>> a.remove(1000) >>> a [0, 3.5, 5.5, 5.5, 7, 7, 200, 1000] >>> del a[2:4] >>> a [0, 3.5, 7, 7, 200, 1000] >>> a.reverse() >>> a [1000, 200, 7, 7, 3.5, 0] # 2. Сравнения и равенство # Простое сравнение >>> a = [1, 5, 10] >>> b = [1, 5, 10] >>> a == b True >>> b[0] = 5 >>> b [5, 5, 10] >>> a  b True # Вложенное сравнение >>> a[0] = [3, "aaa"] >>> b[0] = [3, "bb"] >>> a, b ([[3, 'aaa'], 5, 10], [[3, 'bb'], 5, 10]) >>> a  b True 
3.1.3.1.4. Кортеж¶

Кортеж ( tuple ) — это упорядоченная неизменяемая последовательность элементов.

Особенности: умеет все, что умеет список, за исключением операций, приводящих к изменению кортежа. Применяется в случаях, когда известно, что последовательность не будет меняться после создания.

Создать кортеж можно несколькими способами (Листинге 3.1.14).

Листинг 3.1.14 — Создание кортежа ¶

# 1. Пустой кортеж создается с помощью пустых круглых скобок или функции tuple() >>> () () >>> tuple() () # 2. Инициализировать кортеж элементами можно одним из следующих способов: >>> 1, (1,) >>> 1, 2, "text" (1, 2, 'text') >>> s = tuple("text") >>> s ('t', 'e', 'x', 't') >>> # 3. Т.к. структура является неизменяемой, изменение содержимого запрещено >>> s[0] = "n" Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment 

Кортежи поддерживают все операции, общие для последовательностей.

3.1.3.1.5. Числовой диапазон¶

Числовой диапазон ( range ) — это упорядоченная неизменяемая последовательность элементов — целых чисел.

  • start (int) – начальное значение (по умолчанию 0);
  • stop (int) – конечное значение (не включается в результат);
  • step (int) – шаг изменения (по умолчанию 1, может быть отрицательным).

В Листинге 3.1.15 приведены примеры генерации числовых последовательностей и их отображение на экране в виде кортежа.

Листинг 3.1.15 — Создание числового диапазона ¶

# 10 чисел (от 0 до 9), начиная с 0 с шагом 1 >>> tuple(range(10)) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) # 10 чисел (от 1 до 10), начиная с 1 с шагом 1 >>> tuple(range(1, 11)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) # Числа от 0 до 19 с шагом 5 >>> tuple(range(0, 20, 5)) (0, 5, 10, 15) # Числа от 0 до 20 с шагом 3 >>> tuple(range(0, 20, 3)) (0, 3, 6, 9, 12, 15, 18) # Числа от 0 до -9 с шагом -1 >>> tuple(range(0, -10, -1)) (0, -1, -2, -3, -4, -5, -6, -7, -8, -9) # Следующие 2 объекта range не содержат чисел (нет чисел от 0 до -1 с шагом 1) >>> tuple(range(0)) () >>> tuple(range(1, 0)) () >>> tuple(range(1, 0, -1)) (1,) 

Числовые диапазоны поддерживают те же операции, что и кортежи.

3.1.3.2. Множества¶

Множество — это неупорядоченная коллекция уникальных элементов.

В Python существует 2 класса для работы с множествами:

  • set (изменяемое множество);
  • frozenset (неизменяемое множество).

Элементы множества должны быть хешируемы.

Наиболее часто множества используются для эффективной проверки на вхождение, удаления повторяющихся элементов а также выполнения математических операций, характерных для математических множеств (пересечение, объединение и др.)

Оба типа обладают различиями, схожими с различиями между списком и кортежем.

class set ( [ iterable ] ) ¶ class frozenset ( [ iterable ] ) ¶

Конструкторы классов set и frozenset соответственно.

Создать множество можно несколькими способами (Листинг 3.1.16).

Листинг 3.1.16 — Создание множества ¶
# 1. Пустое множество создается с помощью функции set() >>> set() set() # 2. Инициализировать множество элементами можно, используя: # — фигурные скобки с перечислением элементов; # — функцию set(), передав в качестве аргумента любой итерируемый объект. # Следует обратить внимание, что т.к. множество — неупорядоченный набор данных, # при выводе порядок его элементов может быть произвольным. >>> «a», «b», «c»> >>> set([1, 2, 3, 4, 5])

3.1.3.2.1. Общие операции¶

Пусть st — множество, на котором вызывается метод.

Добавляем элемент elem в множество st .

Удаляет элемент elem из множества st . Если элемент не находится в множестве, возникает ошибка.

Удаляет элемент elem из множества st , если он присутствует в множестве.

Удаляет произвольный элемент из множества st и возвращает в качестве результата.

Удаляет все элементы из множества.

3.1.3.2.2. Математические операции¶

Множества поддерживают математические операции, характерные для множеств (пересечение, объединение и др.), некоторые из которые приведены ниже.

Пусть st — множество, на котором вызывается метод.

union ( other, . ) ¶ st | other | .

Возвращает новое множество — объединение множеств st и other .

intersection ( other, . ) ¶ st & other & .

Возвращает новое множество — пересечение множеств st и other .

difference ( other, . ) ¶ st — other — .

Возвращает новое множество — разность множеств st и other .

Возвращает True если st не содержит общий элементов с other .

Возвращает True если все элементы st содержатся в other .

issuperset ( other ) ¶ st >= other

Возвращает True если все элементы other содержатся в st .

Аналогично st >= other , но множества не должны полностью совпадать.

update ( other, . ) ¶ st |= other | .

Добавляет элементы из other в st .

В Листинге 3.1.17 приведен пример работы с множеством.

Листинг 3.1.17 — Пример работы с множеством ¶
>>> a = 2, 4, 6, 8, 10> >>> b = set(range(11)) >>> a >>> b >>> >>> b.remove(0) >>> b >>> a.add(12) >>> a >>> a & b >>> a | b >>> a b >>> b a

3.1.3.3. Отображения¶

Отображение — это неупорядоченная коллекция пар элементов «ключ-значение». В разных языках синонимом отображений являются термины словарь, хеш-таблица или ассоциативный массив.

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

class dict ( ** kwarg ) ¶ class dict ( mapping , ** kwarg ) class dict ( iterable , ** kwarg )

Создать словарь можно несколькими способами (Листинг 3.1.18).

Листинг 3.1.18 — Создание словаря ¶
# 1. Пустой словарь создается с помощью <> или функции dict() >>> <> <> >>> dict() <> # 2. Инициализировать словарь элементами, используя: # — фигурные скобки с перечислением элементов в виде ‘ключ: значение’; # — функцию dict(), передав набор пар ‘ключ: значение’. # Следует обратить внимание, что т.к. множество — неупорядоченный набор данных, # при выводе порядок его элементов может быть произвольным. >>> «one»: 1, «two»: 2, «three»: 3> >>> dict(one=1, two=2, three=3)

Ниже рассмотрены операции, доступные для словарей.

Пусть d — словарь, на котором вызывается метод.

Возвращает значение словаря для ключа key . Если ключ не существует, возникает ошибка.

Возвращает значение словаря для ключа key . Если ключ не существует возвращается значение default или None .

Устанавливает значение словаря по ключу key . Если ключ не существует, он создается.

Возвращает набор пар «ключ-значение» для словаря d .

Возвращает набор ключей для словаря d .

Возвращает набор значений для словаря d .

Удаляет из словаря все элементы.

Удаляет пару «ключ-значение» на основании ключа key .

В Листинге 3.1.19 приведен пример работы со словарем.

Листинг 3.1.19 — Пример работы со словарем ¶

>>> phonebook = "Петров Петр": "+79102222222"> >>> phonebook["Иванов Сергей"] = "+79101111111" >>> phonebook >>> phonebook["Петров Петр"] '+79102222222' # Обновили номер телефона >>> phonebook["Петров Петр"] = "+79103333333" >>> phonebook >>> "Васильев Василий" in phonebook False >>> phonebook.get("Васильев Василий", "Номер не найден") 'Номер не найден' >>> phonebook.keys() dict_keys(['Иванов Сергей', 'Петров Петр']) >>> phonebook.values() dict_values(['+79101111111', '+79103333333']) 

3.1.4. Еще про объекты и операции¶

3.1.4.1. Общие функции¶

Все объекты независимо от типа поддерживают ряд общих функций.

Возвращает уникальный идентификатор object (для реализации CPython — адрес в памяти).

Возвращает True , если x и y указывают на один и тот же объект.

Отображает справку для object .

Возвращает тип object .

isinstance ( object, class-or-type-or-tuple ) ¶

Возвращает True , если object является классом или подклассом class-or-type-or-tuple .

3.1.4.2. Проверка типов¶

Для того, чтобы проверить, какой тип имеет тот или иной объект можно воспользоваться функциями type() или isinstance() — использование последней для проверки типа более предпочтительно (Листинг 3.1.20).

Листинг 3.1.20 — Функции type() и isinstance() ¶

>>> a = 5 >>> type(a) is int True >>> isinstance(a, int) True # isinstance может принимать вторым параметром кортеж проверяемых типов >>> isinstance(a, (int, float)) True 

3.1.4.3. Взаимное преобразование¶

Все типы поддерживают взаимное преобразование (где оно имеет смысл, например, преобразование списка в кортеж, но не списка в целое число и т.п.), для чего используется конструктор типа с параметром — объектом, который нужно преобразовать. В Листинге 3.1.21 приведены примеры выполнения конвертации.

Листинг 3.1.21 — Взаимное преобразование типов ¶

# 1. Преобразование в строку # Строковое представление имеют практически все рассмотренные классы >>> str(True) 'True' >>> str(5) '5' >>> str(10.43) '10.43' >>> str([1, 2, 3, 4, 5]) '[1, 2, 3, 4, 5]' # 2. Преобразование в целое число >>> int(10.43) # int отсекает дробную часть 10 >>> int("5") 5 >>> int(True) 1 # 3. Преобразование в вещественное число >>> float(5) 5.0 >>> float("10.43") 10.43 # 4. Преобразование в логический тип # Всегда возвращает False, для: # - None, False; # - нулевых чисел; # - пустых последовательностей и отображений. # - . >>> bool(None), bool(0), bool(0.0), bool(""), bool(<>) (False, False, False, False, False) >>> bool(5), bool(1: "первый">) (True, True) # 5. Преобразования последовательностей >>> tuple([1, 2, 3]) (1, 2, 3) >>> d = dict(one=1, two=2, three=2) >>> list(d.keys()) # Получаем список ключей ['one', 'three', 'two'] >>> set(d.values()) # И множество значений >>> 

3.1.4.4. Приоритет операций¶

Операции над объектами выполняются в определенном порядке:

  1. ** .
  2. -x , +x .
  3. * , / , // , % .
  4. + , — .
  5. < , , >= , != , == .
  6. is , is not .
  7. in , not in .
  8. not , and , or .

Изменение порядка можно производить за счет использования скобок, например: (5 + 2) * 3 или (3 * 2)**3 .

3.1.4.5. Поверхностное и глубокое копирование¶

Оператор присваивания копирует ссылку на объект, создавая т.н. поверхностную копию. В ряде случае необходимо создать полную копию объекта (глубокую копию), например, для мутирующих коллекций, чтобы после изменять новую коллекцию без изменения оригинала. Пример различных вариантов копирования приведен в Листинге 3.1.22.

Листинг 3.1.22 — Поверхностное и глубокое копирование объектов ¶

# 1. Поверхностная и глубокая копии >>> x = [53, 68, ["А", "В", "С"]] >>> x1 = x # Поверхностная копия (через присваивание) >>> x2 = x[:] # Глубокая копия (создается при срезе) >>> x3 = x.copy() # Глубокая копия (через метод copy()) >>> >>> id(x), id(x1), id(x2), id(x3) (4813768, 4813768, 4813848, 4813808) >>> x1 is x, x2 is x, x3 is x (True, False, False) # 2. Присваивание копирует ссылки на объекты, создавая объекты при необходимости # Проверить можно с помощью функции id() >>> a = 5 >>> b = a >>> a, b (5, 5) >>> id(a), id(b) (1431495600, 1431495600) >>> c = 5 >>> id(a), id(c) (1431495600, 1431495600) # При изменении значения 'a', Python не изменяет объект 5 # (оставляя его "как есть", т.к. знает, что он используется другими), # а создает новый, меняя ссылку у 'a', при этом прочие объекты продолжают ссылаться на 5 >>> a = 10 >>> id(a), id(c) (1431495680, 1431495600) # Но с мутирующими типами (например, списком) Python поступает по-другому >>> a = [1, 2, 3] >>> b = [1, 2, 3] >>> c = a >>> id(a), id(b), id(c) (30431712, 30447736, 30431712) # При изменении мутирующего типа "изменяются" и указывающие на него объекты - # т.к. они хранят ссылку на тот же объект! >>> a[0] = 5 >>> a, b, c ([5, 2, 3], [1, 2, 3], [5, 2, 3]) 

3.1.4.6. Константы¶

В Python не существует привычного для, например, Си или Паскаля понятия константы. Вместо этого, значение, которое подразумевается как константа, обозначается заглавными буквами ( MEMORY_MAX = 1024 ), визуально предупреждая, что данное значение менять не следует.

3.1.4.7. Сортировка¶

Функция sorted() позволяет получить отсортированный объект в виде списка. В Листинге 3.1.23 приведен пример выполнения сортировки для различных типов коллекций.

Листинг 3.1.23 — Пример использования функции sorted() ¶

# 1. Простой список >>> lst = [1, 8, 2, 5, 0, 3] >>> sorted(lst) [0, 1, 2, 3, 5, 8] >>> sorted(lst, reverse=True) [8, 5, 3, 2, 1, 0] # 2. Словарь # Для словаря sorted() возвращает отсортированный список ключей >>> phones = 'Иван': '+74951111111', 'Сергей': '+74951111113', 'Кирилл': '+74951111112'> >>> sorted(phones) ['Иван', 'Кирилл', 'Сергей'] # 3. Сложная сортировка # Список кортежей: номер элемента, обозначение, название >>> elements = [(1, "Н", "Водород"), (8, "O", "Кислород"), (53, "I", "Йод")] # Используя параметр key, sorted() позволяет сортировать список по # необходимой части коллекции # Сортировка по наименованию (элемент с индексом 2 в кортеже) >>> sorted(elements, key=lambda item: item[2]) [(1, 'Н', 'Водород'), (53, 'I', 'Йод'), (8, 'O', 'Кислород')] # Список чисел >>> nums = [123, 100, 1001, 234, 515] # Сортировка по последней цифре числа по убыванию >>> sorted(nums, key=lambda item: item % 10, reverse=True) [515, 234, 123, 1001, 100] 

3.1.5. Ввод / вывод¶

Обработка данных, как правило, осуществляется после получения данных из какого-либо источника, а после обработки осуществляется их вывод. Для ввода и вывода (в/из терминала операционной системы) в Python используются функции input() и print() соответственно.

Для взаимодействия с терминалом в Python существует 2 функции:

Печатает строку prompt (без переноса строки и если задана) и ожидает ввода пользователя. Ввод подтверждается клавишей , возвращая строку с введенными данными в качестве результата.

print ( * objects , sep = ‘ ‘ , end = ‘\\n’ , file = sys.stdout , flush = False ) ¶

Печатает набор объектов objects , разделенных запятой. При печати все объекты преобразуются в строки.

  • sep – разделитель при выводе нескольких объектов (по умолчанию — пробел);
  • end – строка, завершающая вывод (по умолчанию — перенос строки);
  • file – объект вывода (по умолчанию — терминал).

В Листинге 3.1.24 приведен пример использования функций ввода/вывода.

Листинг 3.1.24 — Пример использования функций ввода/вывода ¶

# 1. Выдать приветствие пользователю >>> name = input("Как тебя зовут? ") Как тебя зовут? Михаил >>> print("Привет,", name, "!") Привет, Михаил ! # 2. Получить длину стороны квадрата (целое число) и вычислить площадь >>> a = int(input("Введите сторону квадрата: ")) Введите сторону квадрата: 15 >>> square = a ** 2 >>> print("Площадь квадрата = <>".format(square)) Площадь квадрата = 225 

Побочный эффект. URL: https://ru.wikipedia.org/wiki/Побочный_эффект_(программирование).

0.30000000000000004 — Floating Point Math. URL: http://0.30000000000000004.com/.

Лучано Рамальо. Python. К вершинам мастерства. — М.: ДМК Пресс , 2016. — 768 с.: ISBN: 978-5-97060-384-0, 978-1-491-94600-8.

Версия: 2023. Обновлено: 16.05.2023.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *