Операторы и выражения в Python

Оглавление

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

В этом уроке вы узнаете об операторах, которые в настоящее время поддерживает Python. Вы также узнаете, как использовать эти операторы для построения выражений.

В этом уроке вы узнаете:

  • Познакомьтесь с арифметическими операторами в Python и используйте их для построения арифметических выражений
  • Изучите операторы сравнения, булевы, идентичности и членства в Python
  • Строить выражения с операторами сравнения, булевыми операторами, операторами тождества и операторами принадлежности
  • Узнайте об операторах Python bitwise и о том, как их использовать
  • Объединять и повторять последовательности с помощью операторов конкатенации и повторения
  • Понимать операторы дополненного присваивания и их работу

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

Начало работы с операторами и выражениями

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

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

>>> -273.15
-273.15

>>> 5 - 2
3

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

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

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

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

>>> 42 == 42
True

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

Говоря о булевых значениях, булевые или логические операторы в Python являются ключевыми словами, а не знаками, как вы узнаете в разделе о булевых операторах и выражениях. Так, вместо странных знаков ||, && и !, которые используются во многих других языках программирования, в Python используются or, and и not.

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

В Python вы найдете несколько категорий или групп операторов. Вот краткий список этих категорий:

  • Операторы присваивания
  • Арифметические операторы
  • Сравнение операторов
  • Булевы или логические операторы
  • Операторы идентичности
  • Членство операторы
  • Конкатенация и повторение операторов
  • Побитовые операторы

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

>>> -
  File "<input>", line 1
    -
    ^
SyntaxError: incomplete input

>>> ==
  File "<input>", line 1
    ==
    ^^
SyntaxError: incomplete input

>>> or
  File "<input>", line 1
    or
    ^^
SyntaxError: incomplete input

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

Итак, что же такое выражение? В Python есть простые и сложные выражения. Простой оператор - это конструкция, занимающая одну логическую строку, например оператор присваивания. Составной оператор - это конструкция, занимающая несколько логических строк, например for цикл или условный оператор. выражение - это простое утверждение, которое производит и возвращает значение.

Во многих выражениях встречаются операторы. Вот несколько примеров:

>>> 7 + 5
12

>>> 42 / 2
21.0

>>> 5 == 5
True

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

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

>>> abs(-7)
7

>>> pow(2, 8)
256

>>> print("Hello, World!")
Hello, World!

В первом примере вы вызываете встроенную функцию abs(), чтобы получить абсолютное значение числа -7. Затем вы вычисляете 2 до степени 8 с помощью встроенной функции pow(). Эти вызовы функций занимают одну логическую строку и возвращают значение. Таким образом, они являются выражениями.

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

Примечание: Все функции Python имеют возвращаемое значение, явное или неявное. Если при определении функции не указать явное значение return, то Python автоматически сделает функцию возвращающей None.

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

Примечание: Начиная с версии 3.8, в Python также появилось то, что называется выражениями присваивания. Это специальные типы присваиваний, которые возвращают значение. Подробнее об этом вы узнаете в разделе Оператор Walrus и выражения присваивания.

Хорошо! Это было краткое введение в операторы и выражения в Python. Теперь пришло время углубиться в эту тему. Для начала вы начнете с оператора присваивания и операторов.

Оператор присваивания и утверждения

Оператор присваивания является одним из наиболее часто используемых операторов в Python. Оператор состоит из одного знака равенства (=) и оперирует двумя операндами. Левым операндом обычно является переменная, а правым - выражение.

Примечание: Как вы уже узнали, оператор присваивания не создает выражение. Вместо этого он создает оператор, который не возвращает никакого значения.

Оператор присваивания позволяет присваивать значения переменным. Строго говоря, в Python этот оператор заставляет переменные или имена ссылаться на конкретные объекты в памяти вашего компьютера. Другими словами, присваивание создает ссылку на конкретный объект и прикрепляет эту ссылку к целевой переменной.

Примечание: Для более глубокого изучения использования оператора присваивания прочитайте статью Python's Assignment Operator: Write Robust Assignments.

Например, все приведенные ниже операторы создают новые переменные, содержащие ссылки на определенные объекты:

>>> number = 42
>>> day = "Friday"
>>> digits = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> letters = ["a", "b", "c"]

В первом операторе вы создаете переменную number, которая содержит ссылку на число 42 в памяти вашего компьютера. Можно также сказать, что имя number указывает на 42, который является конкретным объектом.

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

Вы будете использовать оператор присваивания во многих примерах, которые будете писать на протяжении этого урока. Что еще более важно, вы будете много раз использовать этот оператор в своем собственном коде. Он станет вашим постоянным другом. Теперь вы можете погрузиться в другие операторы Python!

Арифметические операторы и выражения в Python

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

Operator Type Operation Sample Expression Result
+ Unary Positive +a a without any transformation since this is simply a complement to negation
+ Binary Addition a + b The arithmetic sum of a and b
- Unary Negation -a The value of a but with the opposite sign
- Binary Subtraction a - b b subtracted from a
* Binary Multiplication a * b The product of a and b
/ Binary Division a / b The quotient of a divided by b, expressed as a float
% Binary Modulo a % b The remainder of a divided by b
// Binary Floor division or integer division a // b The quotient of a divided by b, rounded to the next smallest whole number
** Binary Exponentiation a**b a raised to the power of b

Обратите внимание, что a и b в столбце Sample Expression представляют числовые значения, такие как integer, с плавающей точкой, комплексные, рациональные и десятичные числа.

Вот несколько примеров использования этих операторов:

>>> a = 5
>>> b = 2

>>> +a
5
>>> -b
-2
>>> a + b
7
>>> a - b
3
>>> a * b
10
>>> a / b
2.5
>>> a % b
1
>>> a // b
2
>>> a**b
25

В этом фрагменте кода сначала создаются две новые переменные, a и b, содержащие 5 и 2 соответственно. Затем вы используете эти переменные для создания различных арифметических выражений, используя определенный оператор в каждом выражении.

Note: The Python REPL will display the return value of an expression as a way to provide immediate feedback to you. So, when you’re in an interactive session, you don’t need to use the print() function to check the result of an expression. You can just type in the expression and press Enter to get the result.

Опять же, стандартный оператор деления (/) всегда возвращает число с плавающей точкой, даже если делимое равномерно делится на делитель:

>>> 10 / 5
2.0

>>> 10.0 / 5
2.0

В первом примере 10 равномерно делится на 5. Поэтому эта операция могла бы вернуть целое число 2. Однако она возвращает число с плавающей точкой 2.0. Во втором примере 10.0 - это число с плавающей точкой, а 5 - целое число. В этом случае Python внутренне повышает 5 до 5.0 и выполняет деление. Результатом также будет число с плавающей точкой.

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

>>> 10 / 5j
-2j

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

Наконец, рассмотрим следующие примеры использования оператора поэтажного деления (//):

>>> 10 // 4
2
>>> -10 // -4
2

>>> 10 // -4
-3
>>> -10 // 4
-3

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

Операторы сравнения и выражения в Python

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

Operator Operation Sample Expression Result
== Equal to a == b • True if the value of a is equal to the value of b
• False otherwise
!= Not equal to a != b • True if a isn’t equal to b
• False otherwise
< Less than a < b • True if a is less than b
• False otherwise
<= Less than or equal to a <= b • True if a is less than or equal to b
• False otherwise
> Greater than a > b • True if a is greater than b
• False otherwise
>= Greater than or equal to a >= b • True if a is greater than or equal to b
• False otherwise

Все операторы сравнения являются бинарными. Это означает, что им требуются левый и правый операнды. Эти операторы всегда возвращают булево значение (True или False), которое зависит от истинного значения рассматриваемого сравнения.

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

>>> 2 == "2"
False

Целое число 2 не равно строке "2". Поэтому в результате получается False. В приведенном выше выражении можно также использовать оператор !=, и тогда в результате получится True.

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

>>> 5 < "7"
Traceback (most recent call last):
    ...
TypeError: '<' not supported between instances of 'int' and 'str'

В этом примере Python вызывает исключение TypeError, потому что сравнение меньше чем (<) не имеет смысла между целым числом и строкой. Таким образом, операция не разрешена.

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

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

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

Сравнение целых значений

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

Рассмотрим следующие примеры, в которых сравниваются целые числа:

>>> a = 10
>>> b = 20
>>> a == b
False
>>> a != b
True
>>> a < b
True
>>> a <= b
True
>>> a > b
False
>>> a >= b
False

>>> x = 30
>>> y = 30
>>> x == y
True
>>> x != y
False
>>> x < y
False
>>> x <= y
True
>>> x > y
False
>>> x >= y
True

В первой серии примеров вы определяете две переменные, a и b, чтобы провести несколько сравнений между ними. Значение a меньше значения b. Таким образом, каждое выражение сравнения возвращает ожидаемое булево значение. Во втором наборе примеров используются два равных значения, и снова вы получаете ожидаемые результаты.

Сравнение значений с плавающей точкой

Сравнение чисел с плавающей точкой немного сложнее, чем сравнение целых чисел. Значение, хранящееся в объекте float, может быть не совсем таким, как вы думаете. По этой причине не стоит сравнивать значения с плавающей точкой на предмет точного равенства с помощью оператора ==.

Рассмотрим пример ниже:

>>> x = 1.1 + 2.2
>>> x == 3.3
False

>>> 1.1 + 2.2
3.3000000000000003

Ой! Внутреннее представление этого сложения не совсем равно 3.3, как вы можете видеть в последнем примере. Таким образом, сравнение x с 3.3 с помощью оператора равенства возвращает False.

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

Модуль math из стандартной библиотеки предоставляет функцию isclose(), которая удобно называется float и поможет вам в сравнении

. Функция берет два числа и проверяет их на примерное равенство:

>>> from math import isclose

>>> x = 1.1 + 2.2

>>> isclose(x, 3.3)
True

В этом примере вы используете функцию isclose() для сравнения x и 3.3 на примерное равенство. На этот раз в результате вы получаете True, потому что оба числа достаточно близки, чтобы считать их равными.

Более подробно об использовании isclose() читайте в разделе "Поиск близости чисел с помощью Python isclose()" в "Модуль Python math": Everything You Need to Know.

Сравнение строк

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

Вы можете использовать встроенную функцию ord(), чтобы узнать кодовую точку Unicode любого символа в Python. Рассмотрим следующие примеры:

>>> ord("A")
65
>>> ord("a")
97

>>> "A" == "a"
False
>>> "A" > "a"
False
>>> "A" < "a"
True

Прописная буква "A" имеет меньшую точку Юникода, чем строчная буква "a". Таким образом, "A" меньше, чем "a". В конце концов, Python сравнивает символы с помощью целых чисел. Поэтому те же правила, которые Python использует для сравнения целых чисел, применимы и к сравнению строк.

Когда речь идет о строках с несколькими символами, Python выполняет сравнение по символам в цикле.

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

>>> "Hello" > "HellO"
True

>>> ord("o")
111
>>> ord("O")
79

В этом примере Python сравнивает оба операнда символ за символом. Дойдя до конца строки, он сравнивает "o" и "O". Поскольку строчная буква имеет большую кодовую точку Юникода, первая версия строки больше второй.

Вы также можете сравнивать строки разной длины:

>>> "Hello" > "Hello, World!"
False

В этом примере Python выполняет посимвольное сравнение, как обычно. Если символы заканчиваются, значит, короткая строка меньше длинной. Это также означает, что пустая строка - наименьшая из возможных строк.

Сравнение списков и кортежей

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

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

>>> [2, 3] == [2, 3]
True
>>> (2, 3) == (2, 3)
True

>>> [5, 6, 7] < [7, 5, 6]
True
>>> (5, 6, 7) < (7, 5, 6)
True

>>> [4, 3, 2] < [4, 3, 2]
False
>>> (4, 3, 2) < (4, 3, 2)
False

В этих примерах вы сравниваете списки и кортежи чисел с помощью стандартных операторов сравнения. При сравнении этих типов данных Python выполняет поэлементное сравнение.

Например, в первом выражении выше Python сравнивает 2 в левом операнде и 2 в правом операнде. Поскольку они равны, Python продолжает сравнивать 3 и 3, чтобы сделать вывод, что оба списка равны. То же самое происходит и во втором примере, где сравниваются кортежи, содержащие одинаковые данные.

Важно отметить, что на самом деле вы можете сравнивать списки с кортежами с помощью операторов == и !=. Однако вы не можете сравнивать списки и кортежи с помощью операторов <, >, <= и >=:

>>> [2, 3] == (2, 3)
False
>>> [2, 3] != (2, 3)
True

>>> [2, 3] > (2, 3)
Traceback (most recent call last):
    ...
TypeError: '>' not supported between instances of 'list' and 'tuple'

>>> [2, 3] <= (2, 3)
Traceback (most recent call last):
    ...
TypeError: '<=' not supported between instances of 'list' and 'tuple'

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

Вы также можете сравнивать списки и кортежи разной длины:

>>> [5, 6, 7] < [8]
True
>>> (5, 6, 7) < (8,)
True

>>> [5, 6, 7] == [5]
False
>>> (5, 6, 7) == (5,)
False

>>> [5, 6, 7] > [5]
True
>>> (5, 6, 7) > (5,)
True

В первых двух примерах в результате получается True, потому что 5 меньше 8. Этого факта достаточно, чтобы Python решил задачу сравнения. Во второй паре примеров вы получаете False. Этот результат имеет смысл, потому что сравниваемые последовательности не имеют одинаковой длины, поэтому они не могут быть равными.

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

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

Двузначные операторы и выражения в Python

В Python есть три булевых или логических оператора: and, or и not. Они определяют набор операций, обозначаемых общими операторами AND, OR и NOT. С помощью этих операторов можно создавать составные условия.

В следующих разделах вы узнаете, как работают булевы операторы в Python. В частности, вы узнаете, что некоторые из них ведут себя по-разному, когда вы используете их с булевыми значениями или с обычными объектами в качестве операндов.

Булевы выражения с булевыми операндами

Вы найдете множество объектов и выражений, которые имеют тип Boolean или bool, как Python называет этот тип. Другими словами, многие объекты оцениваются в True или False, которые являются булевыми значениями в Python.

Например, когда вы оцениваете выражение с помощью оператора сравнения, результат этого выражения всегда имеет тип bool:

>>> age = 20

>>> is_adult = age > 18
>>> is_adult
True

>>> type(is_adult)
<class 'bool'>

В этом примере выражение age > 18 возвращает булево значение, которое вы сохраняете в переменной is_adult. Теперь is_adult имеет тип bool, как вы можете видеть после вызова встроенной функции type().

Вы также можете найти встроенные и пользовательские функции Python, которые возвращают булево значение. Этот тип функций известен как предикатные функции. Встроенные функции all(), any(), callable() и isinstance() являются хорошим примером такой практики.

Рассмотрим следующие примеры:

>>> number = 42

>>> validation_conditions = (
...     isinstance(number, int),
...     number % 2 == 0,
... )

>>> all(validation_conditions)
True

>>> callable(number)
False
>>> callable(print)
True

В этом фрагменте кода вы сначала определяете переменную number с помощью вашего старого друга оператора присваивания. Затем вы создаете еще одну переменную под названием validation_conditions. Эта переменная содержит кортеж выражений. Первое выражение использует isinstance() для проверки того, является ли number целым числом.

Второе - составное выражение, которое сочетает операторы modulo (%) и equality (==) для создания условия, проверяющего, является ли входное значение четным числом. В этом условии оператор modulo возвращает остаток от деления number на 2, а оператор equality сравнивает результат с 0, возвращая True или False в качестве результата сравнения.

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

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

Переменная

number не является вызываемой, и функция, соответственно, возвращает False. Напротив, функция print() является вызываемой, поэтому callable() возвращает True.

Все предыдущие обсуждения являются основой для понимания того, как логические операторы Python работают с булевыми операндами.

Логические выражения, включающие and, or и not, просты, если операнды являются булевыми. Вот краткое описание. Обратите внимание, что x и y представляют булевы операнды:

Operator Sample Expression Result
and x and y • True if both x and y are True
• False otherwise
or x or y • True if either x or y is True
• False otherwise
not not x • True if x is False
• False if x is True

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

Теперь пришло время взглянуть на то, как операторы работают на практике. Вот несколько примеров использования оператора and с булевыми операндами:

>>> 5 < 7 and 3 == 3
True

>>> 5 < 7 and 3 != 3
False

>>> 5 > 7 and 3 == 3
False

>>> 5 > 7 and 3 != 3
False

В первом примере оба операнда возвращают True. Поэтому выражение and возвращает в качестве результата True. Во втором примере левый операнд равен True, а правый - False. Поэтому оператор and возвращает False.

В третьем примере левый операнд - False. В этом случае оператор and немедленно возвращает False и никогда не оценивает условие 3 == 3. Такое поведение называется короткозамкнутой оценкой . Подробнее об этом вы узнаете через некоторое время.

Примечание: Оценка короткого замыкания также называется Оценка Маккарти в честь компьютерного ученого Джона Маккарти.

В последнем примере оба условия возвращают False. И снова and возвращает в качестве результата False. Однако из-за короткого замыкания правое выражение не оценивается.

А как насчет оператора or? Вот несколько примеров, демонстрирующих, как он работает:

>>> 5 < 7 or 3 == 3
True

>>> 5 < 7 or 3 != 3
True

>>> 5 > 7 or 3 == 3
True

>>> 5 > 7 or 3 != 3
False

В первых трех примерах хотя бы одно из условий возвращает значение True. Во всех случаях оператор or возвращает True. Обратите внимание, что если левый операнд равен True, то or применяет замыкание оценки и не оценивает правый операнд. Это имеет смысл. Если левый операнд - True, то or уже знает конечный результат. Зачем ему продолжать оценку, если результат не изменится?

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

Наконец, у вас есть оператор not, который отрицает текущее истинностное значение объекта или выражения:

>>> 5 < 7
True

>>> not 5 < 7
False

Если перед выражением поставить not, то получится обратное истинностное значение. Когда выражение возвращает True, вы получаете False. Когда выражение оценивается в False, вы получаете True.

Существует фундаментальное различие в поведении между not и двумя другими булевыми операторами. В выражении not вы всегда получаете в результате булево значение. Это правило не всегда действует в выражениях and и or, как вы узнаете в разделе "Булевы выражения с другими типами операндов".

Оценка регулярных объектов в булевом контексте

На практике большинство объектов и выражений Python не являются булевыми. Другими словами, большинство объектов и выражений имеют не значение True или False, а значения другого типа. Тем не менее, вы можете использовать любой объект Python в булевом контексте, например, в условном операторе или цикле while.

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

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

По умолчанию объект считается истинным, если в его классе не определен метод __bool__(), возвращающий значение False, или метод __len__(), возвращающий ноль при вызове объекта. Вот большинство встроенных объектов, которые считаются ложными:

  • константы, определенные как ложные: None и False.
  • нули любого числового типа: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
  • пустые последовательности и коллекции: '', (), [], {}, set(), range(0)

(Источник)

Вы можете определить истинностное значение объекта, вызвав встроенную функцию bool() с этим объектом в качестве аргумента. Если bool() возвращает True, то объект является истинным. Если bool() возвращает False, то это фальшь.

Для числовых значений, нулевое значение является ложным, а ненулевое - истинным:

>>> bool(0), bool(0.0), bool(0.0+0j)
(False, False, False)

>>> bool(-3), bool(3.14159), bool(1.0+1j)
(True, True, True)

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

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

Когда дело доходит до оценки строк, вы знаете, что пустая строка всегда ложная, а непустая - правдивая:

>>> bool("")
False

>>> bool(" ")
True

>>> bool("Hello")
True

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

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

>>> bool([])
False
>>> bool([1, 2, 3])
True

>>> bool(())
False
>>> bool(("John", 25, "Python Dev"))
True

>>> bool(set())
False
>>> bool({"square", "circle", "triangle"})
True

>>> bool({})
False
>>> bool({"name": "John", "age": 25, "job": "Python Dev"})
True

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

В общем случае, если .__len__() возвращает 0, то Python считает контейнер фальшивым объектом, что соответствует общим правилам, которые вы только что изучили ранее.

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

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

В качестве операндов для and, or и not можно также использовать любые объекты, например, числа или строки. Можно даже использовать комбинации булевых и обычных объектов. В этих ситуациях результат зависит от истинностного значения операндов.

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

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

Для начала ниже приведена таблица, в которой кратко описано, что получается при использовании двух объектов, x и y, в выражении and:

If x is x and y returns
Truthy y
Falsy x

Важно подчеркнуть одну тонкую деталь в приведенной выше таблице. Когда вы используете and в выражении, вы не всегда получаете True или False в качестве результата. Вместо этого вы получаете один из операндов. Вы получите True или False только в том случае, если возвращаемый операнд имеет одно из этих значений.

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

>>> 3 and 4
4

>>> 0 and 4
0

>>> 3 and 0
0

В первом выражении левый операнд (3) является истинным. Поэтому в результате получается правый операнд (4).

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

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

Примечание: Чтобы глубже изучить оператор and, прочитайте статью Using the "and" Boolean Operator in Python.

При использовании оператора or в качестве результата вы также получаете один из операндов. Вот что происходит для двух произвольных объектов, x и y:

If x is x or y returns
Truthy x
Falsy y

Опять же, выражение x or y не оценивается ни в True, ни в False. Вместо этого оно возвращает один из своих операндов, x или y.

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

>>> 3 or 4
3

>>> 0 or 4
4

>>> 3 or 0
3

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

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

Выражение типа x or y истинно, если истинно либо x, либо y, и ложно, если ложно как x, так и y. Этот тип выражения возвращает первый истинностный операнд, который он находит. Если оба операнда ложные, то выражение возвращает правый операнд. Чтобы увидеть это последнее поведение в действии, рассмотрим следующий пример:

>>> 0 or []
[]

В этом конкретном выражении оба операнда являются фальшивыми. Поэтому оператор or возвращает правый операнд, и в результате все выражение оказывается ложным.

Примечание: Чтобы узнать больше об операторе or, прочитайте статью Using the "or" Boolean Operator in Python.

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

If x is not x returns
Truthy False
Falsy True

Оператор not имеет единообразное поведение. Он всегда возвращает булево значение. Это поведение отличается от поведения его братьев и сестер, операторов and и or.

Вот несколько примеров кода:

>>> not 3
False

>>> not 0
True

В первом примере операнд 3 является истинным с точки зрения Python. Поэтому оператор возвращает False. Во втором примере операнд является ложным, и not возвращает True.

Примечание: Чтобы лучше понять оператор not, прочитайте статью Using the "not" Boolean Operator in Python.

Подводя итог, можно сказать, что оператор Python not отрицает истинностное значение объекта и всегда возвращает булево значение. Это поведение отличается от поведения операторов and и or, которые возвращают операнды, а не булевы значения.

Сложные логические выражения и оценка замыкания

До сих пор вы видели выражения с одним оператором or или and и двумя операндами. Однако вы также можете создавать составные логические выражения с несколькими логическими операторами и операндами.

Чтобы проиллюстрировать, как создать составное выражение с помощью or, рассмотрим следующий игрушечный пример:

x1 or x2 or x3 or ... or xn

Это выражение возвращает первое истинностное значение. Если все предшествующие переменные x являются ложными, то выражение возвращает последнее значение, xn.

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

Чтобы продемонстрировать оценку короткого замыкания, предположим, что у вас есть функция тождества, f(), которая ведет себя следующим образом:

  • Принимает один аргумент
  • Отображает функцию и ее аргумент на экране
  • Возвращает аргумент в качестве возвращаемого значения

Вот код для определения этой функции, а также несколько примеров того, как она работает:

>>> def f(arg):
...     print(f"-> f({arg}) = {arg}")
...     return arg
...

>>> f(0)
-> f(0) = 0
0

>>> f(False)
-> f(False) = False
False

>>> f(1.5)
-> f(1.5) = 1.5
1.5

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

Теперь рассмотрим следующее составное логическое выражение:

>>> f(0) or f(False) or f(1) or f(2) or f(3)
-> f(0) = 0
-> f(False) = False
-> f(1) = 1
1

В этом примере Python сначала оценивает f(0), что возвращает 0. Это значение является ложным. Выражение еще не истинно, поэтому оценка продолжается слева направо. Следующий операнд, f(False), возвращает False. Это значение также является ложным, поэтому оценка продолжается.

Следующим будет f(1). Оно оценивается в 1, что является истиной. В этот момент Python останавливает оценку, потому что уже знает, что все выражение истинно. Следовательно, Python возвращает 1 в качестве значения выражения и никогда не оценивает оставшиеся операнды, f(2) и f(3). Вы можете убедиться из вывода, что вызовы f(2) и f(3) не происходят.

Подобное поведение проявляется в выражении с несколькими операторами and, как, например, в следующем:

x1 and x2 and x3 and ... and xn

Это выражение истинно, если все операнды истинны. Если хотя бы один операнд является ложным, то выражение также является ложным.

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

Вот два примера, которые подтверждают поведение короткого замыкания:

>>> f(1) and f(False) and f(2) and f(3)
-> f(1) = 1
-> f(False) = False
False

>>> f(1) and f(0.0) and f(2) and f(3)
-> f(1) = 1
-> f(0.0) = 0.0
0.0

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

Если все операнды истинны, то Python оценивает их все и возвращает последний (крайний правый) в качестве значения выражения:

>>> f(1) and f(2.2) and f("Hello")
-> f(1) = 1
-> f(2.2) = 2.2
-> f(Hello) = Hello
'Hello'

>>> f(1) and f(2.2) and f(0)
-> f(1) = 1
-> f(2.2) = 2.2
-> f(0) = 0
0

В первом примере все операнды истинны. Выражение также истинно и возвращает последний операнд. Во втором примере все операнды истинны, кроме последнего. Выражение является ложным и возвращает последний операнд.

Идиомы, которые эксплуатируют короткое замыкание оценки

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

  • Предотвращение исключения
  • Предоставление значения по умолчанию
  • Пропуск дорогостоящей операции

Для иллюстрации первого пункта предположим, что у вас есть две переменные, a и b, и вы хотите узнать, дает ли деление b на a число большее, чем 0. В этом случае можно выполнить следующее выражение или условие:

>>> a = 3
>>> b = 1

>>> (b / a) > 0
True

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

>>> a = 0
>>> b = 1

>>> (b / a) > 0
Traceback (most recent call last):
    ...
ZeroDivisionError: division by zero

В этом примере делитель равен 0, что заставляет Python вызвать исключение ZeroDivisionError. Это исключение ломает ваш код. Вы можете пропустить эту ошибку с помощью выражения, подобного следующему:

>>> a = 0
>>> b = 1

>>> a != 0 and (b / a) > 0
False

Когда a равно 0, a != 0 ложно. Замыкание оценки в Python гарантирует, что оценка остановится в этой точке, а значит, (b / a) никогда не выполнится, и ошибка никогда не возникнет.

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

def is_divisible(a, b):
    return b != 0 and a % b == 0

В этой функции, если b является 0, то a / b не определен. Таким образом, числа не являются делимыми. Если b отличается от 0, то результат будет зависеть от остатка от деления.

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

Например, допустим, у вас есть переменная, которая должна содержать название страны. В какой-то момент эта переменная может оказаться пустой строкой. Если это так, то вы хотите, чтобы переменная содержала название страны по умолчанию. Вы также можете сделать это с помощью оператора or:

>>> country = "Canada"
>>> default_country = "United States"

>>> country or default_country
'Canada'

>>> country = ""
>>> country or default_country
'United States'

Если country непусто, то оно истинно. В этом случае выражение вернет первое истинностное значение, которым является country в первом выражении or. Оценка останавливается, и в результате вы получаете "Canada".

С другой стороны, если country является пустой строкой, то это фальшивка. Оценка продолжается до следующего операнда, default_country, который является истинным. Наконец, в результате вы получаете страну по умолчанию.

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

data_is_clean or clean_data(data)

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

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

data_is_updated and process_data(data)

В этом примере оператор and оценивает data_is_updated. Если эта переменная равна true, то оценка продолжается, и функция process_data() запускается. В противном случае оценка останавливается, и process_data() никогда не запускается.

Составные и цепные выражения

Иногда в составном выражении используется оператор and для объединения выражений сравнения. Например, вы хотите определить, находится ли число в заданном интервале. Эту задачу можно решить с помощью составного выражения, например, следующего:

>>> number = 5
>>> number >= 0 and number <= 10
True

>>> number = 42
>>> number >= 0 and number <= 10
False

В этом примере вы используете оператор and для объединения двух сравнительных выражений, которые позволяют узнать, находится ли number в интервале от 0 до 10, оба включены.

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

>>> number = 5
>>> 0 <= number <= 10
True

Это выражение более лаконично и читабельно, чем исходное выражение. Вы можете быстро понять, что этот код проверяет, находится ли число между 0 и 10. Обратите внимание, что в большинстве языков программирования такое цепочечное выражение не имеет смысла. В Python оно работает как шарм.

В других языках программирования это выражение, вероятно, начиналось бы с оценки 0 <= number, которая является истинной. Затем это истинное значение сравнивается с 10, что не имеет особого смысла, поэтому выражение не работает.

Python внутренне обрабатывает этот тип выражения как эквивалентное выражение and, например 0 <= number and number <= 10. Именно поэтому в приведенном выше примере вы получите правильный результат.

Условные выражения или тернарный оператор

В Python есть то, что называется условными выражениями. Эти виды выражений вдохновлены альтернативным оператором , который выглядит как a ? b : c и используется в других языках программирования. Эта конструкция оценивается в b, если значение a истинно, и в противном случае оценивается в c. Из-за этого иногда эквивалентный синтаксис языка Python также называют тернарным оператором.

Однако в Python это выражение выглядит более читабельно:

variable = expression_1 if condition else expression_2

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

if condition:
    variable = expression_1
else:
    variable = expression_2

Итак, зачем Python нужен этот синтаксис? PEP 308 ввел условные выражения, чтобы избежать распространенных, чреватых ошибками попыток достичь того же эффекта, что и традиционный тернарный оператор, используя операторы and и or в выражении, подобном следующему:

variable = condition and expression_1 or expression_2

Однако это выражение работает не так, как ожидалось, возвращая expression_2, когда expression_1 является ложным.

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

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

>>> day = "Sunday"
>>> open_time = "11AM" if day == "Sunday" else "9AM"
>>> open_time
'11AM'

>>> day = "Monday"
>>> open_time = "11AM" if day == "Sunday" else "9AM"
>>> open_time
'9AM'

Когда day равно "Sunday", условие истинно, и в результате вы получаете первое выражение, "11AM". Если условие ложно, то вы получаете второе выражение, "9AM". Обратите внимание, что, как и операторы and и or, условное выражение возвращает значение одного из своих выражений, а не булево значение.

Операторы и выражения идентификации в Python

Python предоставляет два оператора, is и is not, которые позволяют определить, имеют ли два операнда одинаковый идентичность. Другими словами, они позволяют проверить, ссылаются ли операнды на один и тот же объект. Обратите внимание, что идентичность - это не то же самое, что равенство. Последнее направлено на проверку того, содержат ли два операнда одинаковые данные.

Примечание: Чтобы узнать больше о разнице между тождеством и равенством, ознакомьтесь с Python '!=' Is Not 'is not': Сравнение объектов в Python.

Вот краткое описание операторов тождества в Python. Обратите внимание, что x и y - это переменные, которые указывают на объекты:

Operator Sample Expression Result
is x is y • True if x and y hold a reference to the same in-memory object
• False otherwise
is not x is not y • True if x points to an object different from the object that y points to
• False otherwise

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

Вот пример двух переменных, x и y, которые ссылаются на объекты, которые равны, но не идентичны:

>>> x = 1001
>>> y = 1001

>>> x == y
True

>>> x is y
False

В этом примере x и y ссылаются на объекты, значение которых равно 1001. Таким образом, они равны. Однако они не ссылаются на один и тот же объект. Поэтому оператор is возвращает False. Проверить идентичность объекта можно с помощью встроенной функции id():

>>> id(x)
4417772080

>>> id(y)
4417766416

Как можно заключить из вывода id(), x и y не идентичны. То есть это разные объекты, и поэтому выражение x is y возвращает False. Другими словами, вы получаете False, потому что в памяти вашего компьютера хранятся два разных экземпляра 1001.

Когда вы делаете присваивание, например y = x, Python создает вторую ссылку на тот же объект. Подтвердить это можно с помощью функции id() или оператора is:

>>> a = "Hello, Pythonista!"
>>> b = a

>>> id(a)
4417651936
>>> id(b)
4417651936

>>> a is b
True

В этом примере a и b содержат ссылки на один и тот же объект, строку "Hello, Pythonista!". Поэтому функция id() возвращает одно и то же тождество при вызове ее с помощью a и b. Аналогично, оператор is возвращает True.

Примечание: Обратите внимание, что на вашем компьютере при звонке по номеру id() в приведенном выше примере вы получите другой идентификационный номер. Ключевая деталь заключается в том, что идентификационный номер будет одинаковым для a и b.

Наконец, оператор is not является противоположным оператору is. Таким образом, с помощью is not можно определить, не относятся ли два имени к одному и тому же объекту:

>>> x = 1001
>>> y = 1001
>>> x is not y
True

>>> a = "Hello, Pythonista!"
>>> b = a
>>> a is not b
False

В первом примере, поскольку x и y указывают на разные объекты в памяти компьютера, оператор is not возвращает True. Во втором примере, поскольку a и b являются ссылками на один и тот же объект, оператор is not возвращает False.

Примечание: Синтаксис not x is y также работает так же, как и x is not y. Однако первый синтаксис выглядит странно и трудно читается. Поэтому Python признает is not как оператор и поощряет его использование для удобства чтения.

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

Операторы и выражения принадлежности в Python

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

Примечание: Для более глубокого изучения того, как работают тесты принадлежности в Python, ознакомьтесь с Операторы "in" и "not in" в Python: Проверка на принадлежность.

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

Operator Sample Expression Result
in value in collection • True if value is present in collection
• False otherwise
not in value not in collection • True if value is not present in collection of values
• False otherwise

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

Примечание: Синтаксис not value in collection также работает в Python. Однако этот синтаксис выглядит странно и трудно читается. Поэтому, чтобы сохранить код чистым и читабельным, используйте value not in collection, который читается почти как обычный английский.

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

  • Левый операнд: Значение, которое нужно искать в коллекции значений
  • Правый операнд: Коллекция значений, в которой может быть найдено целевое значение

Для лучшего понимания оператора in ниже приведены два наглядных примера, заключающихся в определении того, находится ли значение в списке:

>>> 5 in [2, 3, 5, 9, 7]
True

>>> 8 in [2, 3, 5, 9, 7]
False

Первое выражение возвращает True, потому что 5 находится в списке чисел. Второе выражение возвращает False, потому что 8 отсутствует в списке.

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

>>> 5 not in [2, 3, 5, 9, 7]
False

>>> 8 not in [2, 3, 5, 9, 7]
True

В первом примере вы получите False, потому что 5 находится в списке целей. Во втором примере вы получаете True, потому что 8 отсутствует в списке значений. Из-за отрицательной логики это может показаться нелепым. Чтобы не запутаться, помните, что вы пытаетесь определить, является ли значение не частью заданной коллекции значений.

Операторы и выражения конкатенации и повторения

В Python есть два оператора, которые приобретают несколько иной смысл, когда вы используете их с последовательными типами данных, такими как списки, кортежи и строки. С этими типами операндов оператор + определяет оператор конкатенации, а оператор * представляет оператор повторения:

Operator Operation Sample Expression Result
+ Concatenation seq_1 + seq_2 A new sequence containing all the items from both operands
* Repetition seq * n A new sequence containing the items of seq repeated n times

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

Примечание: Чтобы узнать больше о конкатенации строковых объектов, прочитайте статью Efficient String Concatenation in Python.

Вот несколько примеров того, как оператор конкатенации работает на практике:

>>> "Hello, " + "World!"
'Hello, World!'

>>> ("A", "B", "C") + ("D", "E", "F")
('A', 'B', 'C', 'D', 'E', 'F')

>>> [0, 1, 2, 3] + [4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]

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

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

Примечание: Чтобы узнать больше о конкатенации списков, ознакомьтесь с разделом Concatenating Lists в учебнике Python's list Data Type: Глубокое погружение с примерами.

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

>>> "Hello" * 3
'HelloHelloHello'
>>> 3 * "World!"
'World!World!World!'

>>> ("A", "B", "C") * 3
('A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C')

>>> 3 * [1, 2, 3]
[1, 2, 3, 1, 2, 3, 1, 2, 3]

В первом примере вы используете оператор повторения (*), чтобы повторить строку "Hello" три раза. Во втором примере вы меняете порядок операндов, помещая целое число слева, а целевую строку - справа. Этот пример показывает, что порядок операндов не влияет на результат.

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

Оператор Walrus и выражения присваивания

Обычные операторы присваивания с оператором = не имеют возвращаемого значения, как вы уже узнали. Вместо этого оператор присваивания создает или обновляет переменные. Из-за этого оператор не может быть частью выражения.

Начиная с Python 3.8, вы получили доступ к новому оператору, который позволяет использовать новый тип присваивания. Это новое присваивание называется assignment expression или named expression. Новый оператор называется оператор моржа и представляет собой комбинацию двоеточия и знака равенства (:=).

Примечание: Название walrus происходит от того, что этот оператор напоминает глаза и бивни лежащего на боку моржа. О том, как работает этот оператор, читайте в статье Оператор моржа: Выражения присваивания в Python 3.8.

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

  1. Возвращает результат выражения
  2. Присваивает результат переменной

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

Общий синтаксис выражения присваивания выглядит следующим образом:

(variable := expression)

Это выражение выглядит как регулярное присваивание. Однако вместо оператора присваивания (=) в нем используется оператор моржа (:=). Чтобы выражение работало корректно, в большинстве случаев требуются заключительные круглые скобки. Однако в некоторых ситуациях они не понадобятся. В любом случае, они вам не повредят, поэтому их можно смело использовать.

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

>>> def validate_length(string):
...     if (n := len(string)) < 8:
...         print(f"Length {n} is too short, needs at least 8")
...     else:
...         print(f"Length {n} is okay!")
...

>>> validate_length("Pythonista")
Length 10 is okay!

>>> validate_length("Python")
Length 6 is too short, needs at least 8

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

Выражение присваивания, (n := len(string)), вычисляет длину строки и присваивает ее n. Затем оно возвращает значение, полученное в результате вызова len(), которое в итоге сравнивается с 8. Таким образом, вы гарантируете, что у вас есть ссылка на длину строки для использования в дальнейших операциях.

Побитовые операторы и выражения в Python

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

Operator Operation Sample Expression Result
& Bitwise AND a & b • Each bit position in the result is the logical AND of the bits in the corresponding position of the operands.
• 1 if both bits are 1, otherwise 0.
| Bitwise OR a | b • Each bit position in the result is the logical OR of the bits in the corresponding position of the operands.
• 1 if either bit is 1, otherwise 0.
~ Bitwise NOT ~a • Each bit position in the result is the logical negation of the bit in the corresponding position of the operand.
• 1 if the bit is 0 and 0 if the bit is 1.
^ Bitwise XOR (exclusive OR) a ^ b • Each bit position in the result is the logical XOR of the bits in the corresponding position of the operands.
• 1 if the bits in the operands are different, 0 if they’re equal.
>> Bitwise right shift a >> n Each bit is shifted right n places.
<< Bitwise left shift a << n Each bit is shifted left n places.

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

С помощью побитовых операторов Python можно манипулировать данными на самом тонком уровне - в битах. Эти операторы обычно полезны, когда вы хотите написать низкоуровневые алгоритмы, такие как сжатие, шифрование и другие.

Примечание: Для более глубокого изучения побитовых операторов, ознакомьтесь с Bitwise Operators in Python. Вы также можете посмотреть Build a Maze Solver in Python Using Graphs для примера использования побитовых операторов для построения двоичного формата файла.

Вот несколько примеров, иллюстрирующих, как некоторые побитовые операторы работают на практике:

>>> # Bitwise AND
>>> #   0b1100    12
>>> # & 0b1010    10
>>> # --------
>>> # = 0b1000     8
>>> bin(0b1100 & 0b1010)
'0b1000'
>>> 12 & 10
8

>>> # Bitwise OR
>>> #   0b1100    12
>>> # | 0b1010    10
>>> # --------
>>> # = 0b1110    14
>>> bin(0b1100 | 0b1010)
'0b1110'
>>> 12 | 10
14

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

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

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

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

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

Рассмотрим следующее математическое выражение:

>>> 20 + 4 * 10
60

В этом выражении может быть двусмысленность. Должен ли Python сначала выполнить сложение 20 + 4, а затем умножить результат на 10? Должен ли Python сначала выполнить умножение 4 * 10, а затем сложение?

<<<Поскольку результат

Поскольку результат 60, можно сделать вывод, что Python выбрал последний подход. Если бы он выбрал первый, то результат был бы 240. Это следует стандартному алгебраическому правилу, которое можно встретить практически во всех языках программирования.

Все операторы, которые поддерживает Python, имеют приоритет по сравнению с другими операторами. Этот приоритет определяет порядок, в котором Python выполняет операторы в составном выражении.

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

Вот порядок старшинства операторов Python, с которым вы познакомились до сих пор, от высшего к низшему:

Operators Description
** Exponentiation
+x-x~x Unary positive, unary negation, bitwise negation
*///% Multiplication, division, floor division, modulo
+- Addition, subtraction
<<>> Bitwise shifts
& Bitwise AND
^ Bitwise XOR
| Bitwise OR
==!=<<=>>=isis notinnot in Comparisons, identity, and membership
not Boolean NOT
and Boolean AND
or Boolean OR
:= Walrus

Операторы, расположенные в верхней части таблицы, имеют наивысший приоритет, а операторы, расположенные в нижней части таблицы, имеют наименьший приоритет. Любые операторы в одной строке таблицы имеют равный приоритет.

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

Вот еще один наглядный пример:

>>> 2 * 3 ** 4 * 5
810

В приведенном выше примере Python сначала возводит 3 в степень 4, что равно 81. Затем он выполняет умножение в порядке слева направо: 2 * 81 = 162 и 162 * 5 = 810.

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

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

>>> (20 + 4) * 10
240

>>> 2 * 3 ** (4 * 5)
6973568802

В первом примере Python сначала вычисляет выражение 20 + 4, потому что оно заключено в круглые скобки. Затем Python умножает результат на 10, и выражение возвращает 240. Этот результат полностью отличается от того, что вы получили в начале этого раздела.

Во втором примере Python сначала оценивает 4 * 5. Затем он возводит 3 в степень полученного значения. Наконец, Python умножает результат на 2, возвращая 6973568802.

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

Рассмотрим следующий пример:

(a < 10) and (b > 30)

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

a < 10 and b > 30

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

Дополненные операторы присваивания и выражения

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

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

>>> total = 10
>>> total = total + 5
>>> total
15

В данном примере total - это переменная накопитель, которую вы используете для накопления последовательных значений. Этот пример следует читать так: total равно текущему значению total плюс 5. Это выражение эффективно увеличивает значение total, которое теперь равно 15.

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

>>> count = count + 1
Traceback (most recent call last):
    ...
NameError: name 'count' is not defined. Did you mean: 'round'?

В этом примере переменная count не определена до присваивания, поэтому у нее нет текущего значения. В результате Python поднимает исключение NameError, чтобы сообщить вам о проблеме.

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

>>> total = 10
>>> total += 5
>>> total
15

В выделенной строке используется оператор дополненного сложения (+=). С помощью этого оператора вы создаете присваивание, полностью эквивалентное total = total + 5.

Python поддерживает множество дополненных операторов присваивания. В общем случае синтаксис этого типа присваивания выглядит примерно так:

variable $= expression

Обратите внимание, что знак доллара ($) не является допустимым оператором Python. В данном примере это место для общего оператора. Вышеприведенное утверждение работает следующим образом:

  1. Оцените expression, чтобы получить значение.
  2. Выполните операцию, определяемую оператором, который предшествует оператору присваивания (=), используя текущее значение variable и возвращаемое значение expression в качестве операндов.
  3. Присвойте полученное значение обратно в variable.

В таблице ниже приведена сводка дополненных операторов для арифметических операций:

Operator Description Sample Expression Equivalent Expression
+= Adds the right operand to the left operand and stores the result in the left operand x += y x = x + y
-= Subtracts the right operand from the left operand and stores the result in the left operand x -= y x = x - y
*= Multiplies the right operand with the left operand and stores the result in the left operand x *= y x = x * y
/= Divides the left operand by the right operand and stores the result in the left operand x /= y x = x / y
//= Performs floor division of the left operand by the right operand and stores the result in the left operand x //= y x = x // y
%= Finds the remainder of dividing the left operand by the right operand and stores the result in the left operand x %= y x = x % y
**= Raises the left operand to the power of the right operand and stores the result in the left operand x **= y x = x**y

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

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

Operator Operation Example Equivalent
&= Augmented bitwise AND (conjunction) x &= y x = x & y
|= Augmented bitwise OR (disjunction) x |= y x = x | y
^= Augmented bitwise XOR (exclusive disjunction) x ^= y x = x ^ y
>>= Augmented bitwise right shift x >>= y x = x >> y
<<= Augmented bitwise left shift x <<= y x = x << y

Наконец, операторы конкатенации и повторения также имеют расширенные вариации. Эти варианты по-разному ведут себя с изменяемыми и неизменяемыми типами данных:

Operator Description Example
+= • Runs an augmented concatenation operation on the target sequence.
• Mutable sequences are updated in place.
• If the sequence is immutable, then a new sequence is created and assigned back to the target name.
seq_1 += seq_2
*= • Adds seq to itself n times.
• Mutable sequences are updated in place.
• If the sequence is immutable, then a new sequence is created and assigned back to the target name.
seq *= n

Обратите внимание, что дополненный оператор concatenation работает с двумя последовательностями, а дополненный оператор repetition работает с последовательностью и целым числом.

Заключение

Теперь вы знаете, какие операторы поддерживает Python и как их использовать. Операторы - это символы, комбинации символов или ключевые слова, которые вы можете использовать вместе с объектами Python для построения различных типов выражений и выполнения вычислений в вашем коде.

В этом уроке вы узнали:

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

Другими словами, вы проделали огромную работу! Если вы хотите получить удобную шпаргалку, которая поможет вам вспомнить все, что вы узнали, то нажмите на ссылку ниже:

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

Вернуться на верх