Что делает присваивание ‘x = y или z’ в Python?

#python

#питон #логическое значение #присваивание переменной

Вопрос:

Почему мы видим назначения Python с or помощью ?

Например:

 def my_function(arg_1=None, arg_2=0):
    determination = arg_1 or arg_2 or 'no arguments given!'
    print(determination)
    return determination
 

При вызове без аргументов вышеуказанная функция будет печатать и возвращать 'no arguments given!'

Почему Python делает это, и как можно наилучшим образом использовать эту функциональность?

Ответ №1:

Что or делает выражение «» при присваивании:

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

 x = a or b
 

Если bool(a) возвращает False , то x присваивается значение b

Идентичный вариант использования условных выражений (т.Е. Троичных присваиваний)

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

 def my_function(arg_1=None, arg_2=0):
    determination = arg_1 if arg_1 else arg_2 if arg_2 else 'no arguments given!'
    print(determination)
    return determination
 

Слишком частое повторение этого синтаксиса считается плохим стилем, в противном случае это нормально для однострочников. Недостатком является то, что он немного повторяющийся.

or Выражения

Базовый вариант x or y возвращает x , если bool(x) вычисляется True , иначе он вычисляет y (см. Документы для справки). Таким образом, серия or выражений приводит к возвращению первого элемента, который вычисляется True , или последнего элемента.

Например

 '' or [] or 'apple' or () or set(['banana'])
 

возвращает 'apple' первый элемент, который вычисляется как True , и

 '' or [] or ()
 

возвращает () , даже если оно оценивается как False .

Расширенное and использование

Для контраста x and y возвращает x , если bool(x) вычисляется как False , иначе оно возвращается y .

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

Полезность использования and для присваивания не сразу так очевидна, как использование or , но исторически оно использовалось для троичного присваивания. То есть до того, как была доступна эта более понятная и простая конструкция:

 a = x if condition else y
 

эквивалент, сформированный с помощью логических операторов, был:

 a = condition and x or z                      # don't do this!
 

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

Заключение

Использование логических выражений для присваивания должно выполняться осторожно. Определенно никогда не используйте and для присваивания, что достаточно запутанно, чтобы быть довольно подверженным ошибкам. Поклонники стиля сочтут использование or для присваивания менее предпочтительным (чем более подробное троичное условие, if условие else ), но я обнаружил, что это настолько распространено в профессиональном сообществе Python, что его можно считать идиоматическим.

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

Комментарии:

1. Отличный ответ! Я хотел бы возразить, что вы не должны говорить, оценивает ли что True -то значение or False , а скорее, соответствует ли оно действительности. b = 1 or 2 означает b == 1 , но ни True то, ни другое. Может быть, я просто педантичен или даже сбит с толку?

2. По-видимому, я был недостаточно ясен. 🙂 b = 1 or 2 означает, что сначала он оценивает элемент перед or , и возвращает его, если он оценивается как True (в логическом контексте). Я уточню в тексте как можно СКОРЕЕ. Тем временем ознакомьтесь с документацией по этому вопросу: docs.python.org/2/reference/expressions.html#boolean-operations найдите текст, который начинается со слов «Выражение x или y сначала вычисляет x; если x равно true, возвращается его значение; в противном случае «…

3. О да, я все это знаю. Я просто придираюсь к типажам.