Как выразить условное исполнение внутри Python-лямбды? - PullRequest
4 голосов
/ 28 февраля 2011

Что я обнаружил:

В Погружение в Python Я читал об особой природе операторов and и or и о том, как можно использовать оценку булевых операторов в короткой цепивыразить условные выражения более кратко с помощью и / или трюка , который очень похож на троичный оператор в C.

C:

result = condition ? a : b

Python:

result = condition and a or b

Это кажется полезным, поскольку лямбда-функции в Python ограничены однострочными, но для выражения потока управления используется логический синтаксис.

Начиная с Python 2.5, встроенный if, похоже, пришел на помощь в качестве более читабельного синтаксиса для трюка и / или:

result = a if condition else b

Так что я предполагаю, что это замена на Python дляменее читабельный и / или конструктивный.Даже если я хочу вложить несколько условий, все равно это выглядит довольно всеобъемлющим образом:

result = a if condition1 else b if condition2 else c

Но в мире неопределенности я часто нахожу, что пишу такой код для доступа к abc:

result = a and hasattr(a, 'b') and hasattr(a.b, 'c') and a.b.c or None 

Таким образом, с помощью inline-if я мог бы, вероятно, избавиться от некоторых и и или , что привело бы к вполне читабельному коду:

result = a.b.c if hasattr(a, 'b') and hasattr(a.b, 'c') else None

В этом рецепте 1044 *

result = (a, b)[condition] 

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

Что я хотел бы знать:

Теперь мне интересно, считается ли предпочтительным / более питоническим использованиеinline- if настолько, насколько это возможно, если совместимость с нисходящим потоком не является проблемой, или это всего лишь вопрос вкуса и того, как чувствуешь себя как дома в мире оценки короткого замыкания?

Обновление

Я только что понял, чтоif - это больше, чем синтаксический сахар для трюка and-or-trick, поскольку он не завершится ошибкой, если a равно false в логическом контексте.Так что это, вероятно, более надежно.

Ответы [ 4 ]

2 голосов
/ 28 февраля 2011

Поскольку существует специальная языковая конструкция со встроенным if - else, которая делает то, что вы хотите, и которая была введена для замены уродливых обходных путей, подобных тем, о которых вы упомянули, будет хорошей идеей использовать ее. Тем более, что такие хаки, как трюк and - or, обычно имеют неожиданные угловые случаи / ошибки.

Трюк and - or, например, не срабатывает в этом случае:

a = 0
b = 1
c = True and a or b

c будет 1, а это не то, что вы ожидаете, если ищете семантику if - else.

Так зачем использовать ошибочные обходные пути, если есть языковая конструкция, которая делает именно то, что вы хотите?

2 голосов
/ 28 февраля 2011

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

Точка разрыва будет разной для всех, конечно, но если вы обнаружите, что пишете:

return a.b.c if hasattr(a, 'b') and hasattr(a.b, 'c') else None

Слишком много, рассмотрите просто сделать это вместо:

try:
     return a.b.c
except AttributeError:
     return None
0 голосов
/ 28 февраля 2011

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

try:
    foo = a.b.c

except AttributeError:
    print "woops"

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

РЕДАКТИРОВАТЬ: кстати, Утка набрав .

0 голосов
/ 28 февраля 2011

Я бы предпочел четко указать, что делает мой код. Inline if очень явно выполняет условное присваивание, и читаемость имеет значение. Встроенный, если бы не сделал это на языке, если и / или побочные эффекты считались предпочтительными.

Пеп для условных выражений более подробно описывает, почему был выбран этот конкретный синтаксис, и конкретно обсуждает взлом и / или взлом:

http://www.python.org/dev/peps/pep-0308/

...