2012-01-04 2 views
-2

Существует моя проблема:Python функционального программирования

Пусть у нас есть 3 функции: F, G, H и следующий код

y = f(x) 
a = g(y) 
b = h(y) 

Я хочу сделать это на одной линии, как:

a,b = g(f(x)),h(f(x)) 

, но это не эффективно, если е очень медленно (и не кэширует это результат)

Я ВГА е одно решение с генератором:

a,b = ((g(y),h(y)) for y in (f(x),)).next() 

, но это не очень читаемый

Я хотел бы сделать некоторые вещи, как это:

with f(x) as y: a,b = g(y),h(y) 

Кто-нибудь есть идеи?

(это обмануть

y = f(x);a = g(y);b = h(y) 

)

код

import time 
def f(t): 
    time.sleep(1) 
    print 'f called' 
    return t 

def g(t): return 1 

def h(t): return 2 

a,b = g(f(x)),h(f(x)) 
a,b = ((g(y),h(y)) for y in (f(x),)).next() 
+7

Просто сделайте это 2 строки. – kennytm

+2

Что не так с 'y = f (x); a, b = (g (y), h (y)) '? – Marcin

+0

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

ответ

6

Используйте лямбда. Ta-дах !:

>>> def f(a): 
...  return a+1 
... 
>>> def g(a): 
...  return a*2 
... 
>>> def h(a): 
...  return a*3 
... 
>>> (lambda x: (g(x),h(x)))(1) 
(2, 3) 
>>> (lambda x: (g(x),h(x)))(f(1)) 
(4, 6) 
>>> a,b=(lambda x: (g(x),h(x)))(f(1)) 
>>> a 
4 
>>> b 
6 
+2

imho, это не является более коротким и читаемым, чем старый добрый 'y = f (x); a, b = g (y), h (y) '" cheat " – joaquin

+0

Конечно, это не так, но это ответ на вопрос :) – opqdonut

+0

да, и интересный, поэтому я не поддержал его. Mine был просто комментарием (о том, что часто более идиоматический способ также является самым простым) – joaquin

3

Я, вероятно, отсутствует пункт здесь, но я не вижу ничего плохого в

y = f(x); a,b = (g(y), h(y)) 

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

def xmap(v, f_iter): 
    "Subjects v to every function in f_iter and returns a list of results" 
    return [f(v) for f in f_iter] 

вы можете сделать:

a, b = xmap(f(x), [g, h]) 

map идиомы хорошо известен поэтому такой подход, возможно, читаемый и вполне понятно, то есть xmap(), как map() но с арг и funcs транспонированная.

+0

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

+1

@ пользователь1129519 достаточно справедливый. Могу ли я спросить, почему вы пытаетесь выполнять функциональное программирование с помощью Python? Если вы изучаете Python, разве вы не должны фокусироваться на питонических идиомах, а не на других парадигмах? –

+0

Python поддерживает несколько парадигм программирования, прежде всего, но не ограничиваясь объектно-ориентированным, императивным и, в меньшей степени, стилями функционального программирования (wikipaedia) – joaquin

1

Если вы хотите использовать with заявление, вы можете просто украсить f() с contextlib.contextmanager и выход из него:

from contextlib import contextmanager 

@contextmanager 
def f(t): 
    time.sleep(1) 
    print 'f called' 
    yield t 

with f(1) as y: 
    a, b = g(y), h(y) 
+0

Благодарим вас за то, что я открыл для себя новые функции python ... – user1129519

Смежные вопросы