Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Результат логических операций Основы языка Python

Посмотрите на код ниже и попробуйте угадать, что будет напечатано на экран?

print(0 or 1)

Правильный ответ:

1

Оператор ИЛИ работает так, что его выполнение (слева направо) прерывается и возвращается результат первого аргумента, который можно преобразовать в True, если такого аргумента нет, возвращается последний (правый).

Пример:

print(0 and 1)
0

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

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

  • 0, 0.0, '', None, приводятся к False. Эти значения называют falsy. Сюда входят еще некоторые другие типы данных, которые мы пока не проходили, но будем изучать на Хекслете.
  • Всё остальное приводится к True

Этим активно пользуются в разработке, например, для определения значения по умолчанию:

value = name or ''
# Примеры
234 or '' # 234
'hexlet' or '' # 'hexlet'
None or '' # ''

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

Но здесь есть потенциальный баг. Если name содержит falsy значение, а присваивание переменной value значений типа 0, False, None, допустимо, то код выше начнёт работать неверно:

# Упс. Значение на самом деле есть,
# но оно является Falsy, поэтому не выбирается на условии OR
False or '' # ''
0 or '' # ''
None or '' # ''

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

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

# число четное
result = 10 % 2 == 0 and 'yes' or 'no' # 'yes'
# или сразу печатаем на экран
print(10 % 2 == 0 and 'yes' or 'no') # => 'yes'
# число нечетное
print(11 % 2 == 0 and 'yes' or 'no') # => 'no'

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

# Для четного
# 1 шаг
10 % 2 == 0 # True
# 2 шаг
True and 'yes' # результат истина
# проверка на or выполняется, но правая часть не исполняется, так как сразу возвращается 'yes'

# Для нечетного
# 1 шаг
11 % 2 == 0 # False
# 2 шаг
False and 'yes' # результат ложь, проверяем дальше
# 3 шаг
False or 'no' # выбирается и возвращается 'no'

Точно такую же схему можно использовать с любым выражением в начале

print(somefunc() and 'yes' or 'no')

Проверьте себя, поэкспериментируйте с кодом в репле https://replit.com/@hexlet/python-basics-logical-expressions

Двойное отрицание

Вспомните операцию отрицания:

answer = True
print(not answer)  # => False

При двойном отрицании итоговое значение равно начальному:

answer = True
print(not not answer)  # => True

Но здесь дополнительно происходят преобразования типа. Поэтому результатом двойного отрицания всегда будет значение типа boolean.

Ошибка выбора

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

value == ('first' or 'second')

В голове мы это себе примерно так и представляем, но языки работают по другому, поэтому такой код приведет к неверному результату. Как его правильно прочитать? Мы должны вспомнить приоритет выполнения операций. Первым делом вычисляется все что указано в скобках, то есть 'first' or 'second'. Если выполнить этот код в репле, то вывод будет таким:

python
Python 3.8.2 (default, Apr 12 2020, 15:53:37)
>>> 'first' or 'second'
'first'
>>>

Теперь мы можем заменить исходное выражение, на частично вычисленное:

value == 'first'

Совсем не то, что мы ожидали. А теперь вернемся к началу и напишем проверку правильно:

# Скобки ставить не обязательно,
# потому что приоритет == выше чем приоритет or
value == 'first' or value == 'second'

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

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

Открыть доступ

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

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Python-разработчик
Профессия
Разработка веб-приложений на Django
7 июля 10 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»