2015-06-02 11 views
5

natknąłem się na dość sprytny funkcji, które ma dwie funkcje, obowiązuje jedna na siebie podano argument x:Dlaczego ta lambda wymaga * arg, jaka to różnica?

def compose(f,g): 
    return lambda *x: f(g(*x)) 

Teraz mój problem jest z *x, a ja nie widzę naprawdę robi cokolwiek tutaj. Dlaczego nie może być proste x (bez gwiazdki)?

Oto moje testy:

>>> def compose(f,g): 
... return lambda *x: f(g(*x)) 
... 
>>> this = lambda i: i+1 
>>> that = lambda b: b+1 
>>> compose(this,that)(2) 
4 

>>> def compose(f,g): 
... return lambda x: f(g(x)) 
... 
>>> compose(this,that)(2) 
4 

>>> def compose(f,g): 
... return lambda *x: f(g(*x)) 
... 
>>> compose(this,that)(2,2) 
TypeError: <lambda>() takes exactly 1 argument (2 given) 
+4

@jonrsharpe, podczas gdy wyjaśnia '*'/'**' - Nie sądzę, że wyjaśnia kontekst tego pytania –

Odpowiedz

4

Jeśli g (that w badaniach) może mieć również zmienną liczbę argumentów, a następnie lambda *x: f(g(*x)) mogą być użyteczne.

W przeciwnym razie, nie za bardzo.

Celem jest umożliwienie wywołania złożonej funkcji z dowolną liczbą argumentów i przekazanie wszystkich tych argumentów do wewnętrznej funkcji w kompozycji.

+3

Na przykład: compose (abs, min) (1,2, -5, -3, - 6,12, -9) – dexgecko

1

Problem ze swoimi testów jest to, że funkcje skład this i that akceptuje tylko jeden argument, więc punkt * w funkcji compose jest tracona (i komunikat „trwa dokładnie 1 argumentu” błąd) .

Moc operatora * staje się oczywiste, gdy chcesz przekazać w rozpakowanych krotek, a twoje lambdas wesprzeć w ten sposób:

Spróbuj prostą mapę zmniejszyć przykład:

this = lambda *i: *[x**2 for x in i] # map tuple i 
that = lambda *b: sum(b) # reduce tuple b 

def compose(f,g): 
    return lambda *x: f(*g(*x)) 

compose(that,this)(2,2) 
3

celu uzupełnienia @ odpowiedź Fryderyka byłoby najbardziej elastyczny jeśli compose stosowany standard *args, **kwargs construct:

def compose(f,g): 
    return lambda *args, **kwargs: f(g(*args, **kwargs)) 

ten sposób, compose działa z każdą funkcją g, niezależnie od podpisu g.

Ten na twoje pytanie używa tylko pierwszej części, tj. *args i używa innej (niekonwencjonalnej) nazwy, *x.

Powiązane problemy