"Логические" операции в Python (т. е. операторы and/or)
этот метод ищет первую группу символов слова (т. е.:[a-zA-Z0-9_]), возвращая первую совпадающую группу или None в случае неудачи.
def test(str):
    m = re.search(r'(w+)', str)
    if m:
        return m.group(1)
    return None
та же функция может быть переписана следующим образом:
def test2(str):
    m = re.search(r'(w+)', str)
    return m and m.group(1)
это работает так же, и описанное поведение; как на этой странице четко указано:
выражение
x and yсначала оцениваетx; еслиxложно, то его значение возвращается; в противном случаеyis вычисляется и полученное значение возвращается.
однако, будучи логическим оператором (он даже говорит об этом в руководстве), я ожидал and для возврата логического значения. В результате я был удивленные когда я узнал (как) это работает.  
каковы другие варианты использования этого и / или каково обоснование этой довольно неинтуитивной реализации?
5 ответов
каковы другие варианты использования этого
лаконичность (а значит ясность, как только к ней привыкнешь, так как все-таки она делает не пожертвовать читабельностью вообще!- ) в любое время вам нужно что-то проверить и либо использовать это что-то, если это правда, либо другое значение, если это что-то ложно (это для and -- reverse it for or - и я очень умышленно избегая реального запросам-или-как True и False, Я говорю о каждый объект, а не просто bool!-).
вертикальное пространство на любом экране компьютера ограничено, и, учитывая выбор, его лучше всего потратить на полезные средства чтения (docstrings, комментарии, стратегически размещенные пустые строки для разделения блоков, ...) чем в повороте, скажем, такой строки, как:
inverses = [x and 1.0/x for x in values]
в шесть, таких как:
inverses = []
for x in values:
    if x:
        inverses.append(1.0/x)
    else:
        inverses.append(x)
или более тесные версии.
и / или каково обоснование этого довольно сложным в реализации?
отнюдь не будучи "неинтуитивными", новички регулярно спотыкались о то, что некоторые языки (например, стандартный Паскаль) делали не укажите порядок оценки и характер короткого замыкания and и or; одно из различий между Turbo Pascal и языковым стандартом, который в свое время сделал Turbo самым популярным диалектом Паскаля раз, было именно то, что Turbo реализовано and и or так же, как Python сделал позже (и язык C сделал раньше...).
каковы другие варианты использования этого
нет.
каково обоснование этой довольно неинтуитивной реализации?
"нелогично"? Неужели? Я бы не согласился.
давайте подумаем.
 " a и b " фальсифицируется, если a является false.  Поэтому первого ложного значения достаточно, чтобы знать ответ.  Зачем беспокоиться о преобразовании a на другой логический?  Это уже ложный.  Насколько больше ложь False?  Тоже ложь, верно?  
так a ' s значение -- когда эквивалентно False -- достаточно ложно, так что это значение всего выражения.  Нет дальнейшего преобразования или обработки.  Сделанный. 
, когда a ' s значение эквивалентно True затем  - это все, что требуется. Нет дальнейшего преобразования или обработки.  Зачем трансформировать b на другой логический?  Это все, что нам нужно знать.  Если это что-то как True, то это правда.  Насколько вернее True?
зачем создавать ложные дополнительные объекты?
тот же анализ для или.
почему преобразование в Boolean? Это уже достаточно верно или достаточно ложно. Насколько правдивее это может быть?
Попробуйте Это.
>>> False and 0
False
>>> True and 0
0
>>> (True and 0) == False
True
пока (True and 0) на самом деле 0, равен False.  Это ложь-достаточно для всех практических цели.
если это проблема, то bool(a and b) принудит явное преобразование.
Я не нашел это удивительным, и на самом деле ожидал, что это сработает, когда я изначально попробовал.
пока не все значения bools, обратите внимание, что в действительности все значения boolean--они представляют ценность истины.  (В Python, a bool и--в результате--значение, которое только представляет true или false.) Число 0 не является bool, но он явно (в Python) имеет логическое значение False.
другими словами, логический оператор and не всегда возвращает bool, но это всегда возвращает логическое значение; тот, который представляет true или false, даже если он также имеет другую информацию, логически присоединенную к нему (например. строка.)
возможно, это ретроактивное оправдание; я не уверен, но в любом случае кажется естественным, что булевы операторы Python ведут себя так, как они.
когда его использовать?
в вашем примере test2 чувствует себя яснее для меня. Я могу сказать, что они оба делают одинаково: конструкция в test2 не делает ее более трудной для понимания. Все остальное равно, более сжатый код в test2-незначительно-быстрее понимается. Тем не менее, это тривиальная разница, и я не хочу, чтобы я переписывал что-либо.
это может быть также полезно и другими способами:
a = {
    "b": a and a.val,
    "c": b and b.val2,
    "d": c and c.val3,
}
это может быть переписано по-другому, но это ясно, просто и лаконично.
Не выходите за борт; " a () и b () или c ()" в качестве замены "a ()? b (): c ()" опасно и запутанно, так как вы закончите с c (), если B () ложно.  Если вы пишете терниарное утверждение, используйте терниарный синтаксис, даже если он ужасно уродлив:b() if a() else c().
в принципе a and b возвращает операнд, который имеет то же значение истинности, что и все выражение. 
это может показаться немного запутанным, но просто сделайте это в своей голове: если a is False, потом b больше не имеет значения (потому что False and anything всегда будет False), поэтому он может вернуться a сразу. 
но когда a is True затем только b имеет значение, поэтому он возвращается b сразу, даже не глядя.
это очень общая и очень базовая оптимизация на многих языках.
Я думаю, что, хотя эта нотация "работает", она представляет собой плохой стиль кодирования, который скрывает логику и запутает более опытных программистов, у которых будет "багаж" знаний о том, как работает большинство других языков.
в большинстве языков возвращаемое значение активной функции определяется типом функции. Если только он явно не перегружен. Пример функция типа "strlen" должна возвращать целое число, а не строку.
в строке такие функции, как основные артритные и логические функции (+ -|*/&!) являются еще более сдержанными, потому что за ними также стоит история формальной математической теории. (Подумайте обо всех аргументах о порядке операций для этих функций)
чтобы фундаментальные функции возвращали что-либо, кроме их наиболее распространенного типа данных (логического или числового), следует классифицировать как целенаправленное запутывание.
в почти каждом общем языке " & " или "& & " или " и " является логикой или Булева функция. За кулисами компиляторы оптимизации могут использовать короткую логику резания, как указано выше, в логическом потоке, но не модификацию структуры данных (любой оптимизирующий компилятор, который изменил значение таким образом, считался бы сломанным), но если ожидается, что значение будет использоваться в переменной для дальнейшей обработки, оно должно быть в логическом или булевом типе, потому что это "формальное" для этих операторов в большинстве случаев.
