Python: Маленькая хитрость. if-else vs and-or

На этот раз будет мини-заметка, уж слишком мне понравился трюк, о котором пойдёт речь дальше.

Наверное любому программисту приходится часто писать конструкции такого вида:

Как-то разбирая исходники какого-то проекта (скорее всего, это была Django) наткнулся на весьма компактную замену. Вот для сравнения два аналогичных блока кода с использованием логических операций python’а и с использованием конструкции if-else:

На мой взгляд выглядит гораздо лучше и компактнее (да-да, if-else можно записать в 2 строчки вместо 4, но мне так не нравится). Другое дело, что некоторым это может показаться противоречиво с некоторыми пунктами дзена python’а (import this), но это спорно. В общем использую там, где считаю нужным.

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

Тесты привёл, теперь объяснение.

Дело в том, что логические операции and и or в python’е возвращают один из операндов. Операция and возвращает первый операнд, если он приводится к логическому типу False, иначе — второй. Операция or наоборот, возвращает 1й операнд, если он приводится к типу True, иначе — второй. Всё это связано с «ленивостью» (lazy) операций, вычисляется столько аргументов, сколько надо для того, чтобы однозначно определить результат (например, 1 or x всегда даёт True, поэтому x не вычисляется).

Update (17.02.2013): сквозь призму опыта, спустя достаточно большой промежуток времени, могу посоветовать оставить в стороне джедайские техники. Максимум, используйте только один оператор: x = y and z или x = y or z. Да и то, сначала подумайте, может if/else одной строкой будет наглядней? Хотя, конструкция «x = y if z else a» поддерживается только начинаю с Python 2.5, но я надеюсь вас это ограничение не затрагивает.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: