Как делать «и» и «или» работа, когда объединены в одном утверждении?

StackOverflow https://stackoverflow.com/questions/2579959

Вопрос

По какой-то причине эта функция путала меня:

def protocol(port):
    return port == "443" and "https://" or "http://"

Может кто-нибудь объяснить порядок того, что происходит за кулисами, чтобы сделать эту работу так, как она делает.

Я понял это как это, пока не попробую это:

Либо)

def protocol(port):
    if port == "443":
        if bool("https://"):
            return True
    elif bool("http://"):
        return True
    return False

Или б)

def protocol(port):
    if port == "443":
        return True + "https://"
    else:
        return True + "http://"

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

Это было полезно?

Решение

Это старая Иш идиома; вставка скобок, чтобы показать приоритет,

(port == "443" and "https://") or "http://"

x and y возвращается y если x трюша, x если x является фальсивом; a or b, наоборот, возвращается a Если это трехи, в противном случае b.

Так что если port == "443" верно, это возвращает RH and, т.е. "https://". Отказ В противном случае то and неверно, так что or попадает в игру и возвращает `" http: // ", это RHS.

В современном Python, лучший способ сделать перевести этот старый ISH IDIOM:

"https://" if port == "443" else "http://"

Другие советы

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

C and X or Y Долгосовая ранняя попытка пользователей Python к прокси для C ? X : Y

По большей части это работает, Кроме если X является False - это привело к многим ошибкам в коде Python, так что в Python FAQ, вы найдете более правильное решение (C and [X] or [Y])[0] потому что список с одним элементом, независимо от его оцениваемого логического значения, всегда TrueДействительно Например: [None] является True но None нет. Пример ОП выше работает, потому что строка, представляющая X не пусто.

Тем не менее, все это изменилось в Python 2.5, когда на языке добавляли тройник или условный оператор, позволяя использовать очиститель X if C else Y Как указано в других сообщениях здесь. Если вы увидите код, используя более старый формат, это потому, что пользователь был длительным временем Python Programmer, который еще не принял новый синтаксис, они сокращают другой старый код, или их работодатель все еще использует 2.4.x ( или более ранние релизы) и т. Д.

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

Вот пример того, как and/or IDIOM может дать неожиданный результат:

>>> foo = 'foobar'
>>> bar = 'foobar'
>>> x = 0
>>> y = 1
>>> (foo == bar) and x or y   # Will this return the value of x if (foo == bar)?
1

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

return "https://" if port == "443" else "http://"

Вы можете захотеть прочитать на «и / или трюк» Python в этой статье Своеобразная природа и или или в Python. Отказ Это немного похоже на IIF() в VBA или VB или ?: в языках C-стиля.

Эта конструкция работает, потому что это «разворачивается» к следующему коду:

A и B ->

if a:
  return b
else:
  return a

A или B ->

if a:
  return a
else:
  return b

Со всеми хорошими ответами я нашел эти заявления, помогите мне помнить это лучше и подходят, как работает мой мозг (и, надеюсь, для некоторых больше там):

  • «И» возвращает первый ложный элемент (например, None, «», [], (), {}, 0) или последний элемент, если нет (например, не найдено ложным)

  • «Или» возвращает первый истинный элемент или последний пункт (например, NO TRUEN НАЙДЕНА) **

В итоге:

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

Примечание. Это правило также относится к цепочку «и» или «или« или «или» или «

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top