Скобки в условных выражениях Python
У меня простой вопрос по поводу использования скобок в условных операторах Python.
Следующие два фрагмента кода работают одинаково, но я задаюсь вопросом, правда ли это только из-за их простоты:
import os, socket
if ((socket.gethostname() == "bristle") or (socket.gethostname() == "rete")):
DEBUG = False
else:
DEBUG = True
DEBUG
и теперь без скобок:
import os, socket
if socket.gethostname() == "bristle" or socket.gethostname() == "rete":
DEBUG = False
else:
DEBUG = True
DEBUG
Может кто-то помочь прояснить этот вопрос? Существуют ли какие-либо случаи, когда я определенно должен использовать скобки?
4 ответ(ов)
Другие ответы, утверждающие, что сравнение происходит перед булевыми операциями, абсолютно верны. В качестве альтернативы (в ситуациях, подобных той, что вы продемонстрировали), вы также можете использовать следующий способ комбинирования условий:
if socket.gethostname() in ('bristle', 'rete'):
# Здесь что-то делаем, когда условия выполняются.
Это позволяет избежать отдельных вызовов socket.gethostname
и упрощает добавление дополнительных допустимых значений по мере роста вашего проекта или необходимости авторизовать новые хосты.
Круглые скобки служат для задания порядка выполнения операций. Если у вас есть дополнительная часть в условии, например, and
, рекомендуется использовать скобки, чтобы обозначить, с каким or
связан этот and
.
Например:
if (socket.gethostname() == "bristle" or socket.gethostname() == "rete") and var == condition:
...
Это условие будет отличаться от следующего:
if socket.gethostname() == "bristle" or (socket.gethostname() == "rete" and var == condition):
...
В первом случае проверяется, соответствует ли имя хоста одному из двух значений, и затем уже сравнивается с var
. Во втором случае var
сравнивается только с одним из условий для второго имени хоста. Без скобок можно запутаться в порядке операций, что может привести к ошибкам. Поэтому использование скобок поможет сделать код более читаемым и избежать логических ошибок.
В данном случае скобки избыточны. Операции сравнения имеют более высокий приоритет, чем логические операторы, поэтому сравнения всегда будут выполняться первыми, независимо от скобок.
Тем не менее, есть одно правило, которое я однажды видел (возможно, в Practical C Programming), которое гласит следующее:
- Сначала умножение и деление
- Затем сложение и вычитание
- Скобки вокруг всего остального
(Да, если мне не изменяет память, они пропустили возведение в степень!)
Смысл в том, что правила приоритета операций достаточно сложны, чтобы никто не мог ожидать, что каждый запомнит их все, как оригинальный программист, так и специалист по поддержке, читающий код. Поэтому лучше сделать это явным. Фактически, скобки служат как для явной передачи намерений компилятору, так и в качестве документации для следующего, кто будет с этим работать.
Я полагаю, что в Python эти два выражения сгенерируют одинаковый байт-код, так что вы даже не теряете в производительности.
Проблема, с которой вы столкнулись, возникает из-за того, как интерпретируются операторы в вашем условном выражении. Давайте разберемся.
Ваше первое условие выглядит так:
if count1==0 & count2==0 & count3==0:
В этом случае оператор &
используется для битового "И", а не для логического "И". Битовый оператор выполняет побитовые операции, что может привести к неожиданным результатам. Например, если count1
, count2
и count3
— это целые числа, то выражение сначала оценивает count1==0
, что возвращает True
(или 1
), затем выполняется битовая операция &
с count2==0
, и так далее.
Поэтому логическое выражение неправильно рассчитывается, и итоговый результат может быть неверным.
Ваше второе условие:
if (count1==0) & (count2==0) & (count3==0):
здесь будет работать аналогично, используя побитовый &
, но если все условия истинны, побитовая операция завершится правильно, возвращая 1
. Однако правильнее использовать логический оператор and
, что будет более семантически верно в данном контексте:
if count1==0 and count2==0 and count3==0:
Использование and
таким образом делает код более читаемым и предотвращает путаницу, так как он сразу указывает, что вы работаете с логическими значениями.
Так что, в заключение, используйте and
для логических операций вместо &
, чтобы избежать подобных недоразумений в будущем.
Как изменить порядок столбцов в DataFrame?
'pip' не распознан как командa внутреннего или внешнего формата
Почему statistics.mean() работает так медленно?
Преобразование строки даты JSON в datetime в Python
Есть ли разница между поднятием экземпляра класса Exception и самого класса Exception?