Повторно использовать вывод функции в условии if-else без временного - PullRequest
0 голосов
/ 08 июня 2018

Привет и спасибо за проверку, я программирую на Python и у меня простой вопрос, на который я до сих пор не нашел ответа.У меня есть вывод функции, который мне нужно использовать несколько раз в операторе if-else.

Вот пример кода:

result = fooB(fooA()) if fooA()==*someComparison* else fooA()

Есть ли элегантный способ использовать такую ​​функциювыводить несколько раз без многократного вызова функции (вычислительно дорого) или необходимости временно сохранять выходные данные в предыдущей строке?

Ответы [ 3 ]

0 голосов
/ 08 июня 2018

Я бы просто присвоил значение переменной в предыдущей строке, если бы оно было одинаковым для всех трех вызовов.

Как уже писал Хирнер в комментариях, ваш пример немного сбивает с толку, так как выВы никому не назначаете значение троичного, подразумевая, что fooB(x) - это некоторая функция с побочными эффектами, которую вы хотите вызвать, но не назначаете переменной.Я думаю, что в этом случае использование тернарного оператора не очень красиво.

В случае, если fooB(fooA()) возвращает значение, которое вы хотите присвоить, если сравнение истинно, или же назначить fooA(), тогда

a = fooA()
b = fooB(a) if a == bar else a

- это, безусловно, правильный путь, и он не особенно неэлегатный.

В случае, если fooB - это некоторая функция с побочными эффектами, которую вы хотите вызывать, только если сравнение верно, вы можете написать, например,

a = fooA()
a == bar and fooB(a)

, но не всем нравится этот идиома, поэтому

a = fooA()
if a == bar:
    fooB(a)

может быть предпочтительнее ...

0 голосов
/ 08 июня 2018

Пока что то, что вы хотите, невозможно, потому что тернарный оператор python допускает только выражения, а не операторы.Если вам интересно узнать разницу, я бы порекомендовал прочитать этот удивительный ответ по теме .Но важной частью этого вопроса является то, что вы запрашиваете задание (то есть что-то вроде tmp = fooA(), как вы правильно заметили), что является утверждением.

К счастью, другие люди, такие как вы (и я) был бы признателен за возможность обмениваться временными результатами в одном блоке, выражении или операторе, что является целью PEP 572 , которая должна появиться в конце 2019 года для python3.8. Учитывая, что PEP принят.

Вы уже можете попробовать это, скомпилировав POC из исходного кода.Вот как это выглядело бы:

>>> my_func = lambda: 'foo'
>>> tmp + 'bar' if (tmp := my_func()) == 'foo' else tmp
foobar
>>> tmp + 'bar' if (tmp := my_func()) == 'baz' else tmp
foo

Что намного красивее и прямолинейнее, чем то, что вы сейчас делаете с временными переменными:

>>> tmp = my_func()   # store the temp var
>>> if tmp == 'foo':  # the test
...    tmp += 'bar'   # the optional change
>>> tmp               # printing/reassigning the temp var
foobar
0 голосов
/ 08 июня 2018

Если fooA() зависит только от его аргументов, вы можете использовать памятку, но у вас все равно будут трижды вызываться функция (и, конечно, накладываться расходы на поиск кэша заметок), так что ответ - нетединственное разумное решение здесь - однозначно сохранить результат первого вызова в промежуточной переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...