sintaxis - lambda python 3 español
¿Puede una función lambda llamarse recursivamente en Python? (11)
Una función regular puede contener una llamada a sí misma en su definición, no hay problema. Sin embargo, no puedo descifrar cómo hacerlo con una función lambda por la sencilla razón de que la función lambda no tiene un nombre al que remitirse. ¿Hay una manera de hacerlo? ¿Cómo?
Al contrario de lo que dijo, PUEDES hacer esto directamente.
(lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))(n)
La primera parte es el combinador de punto fijo Y que facilita la recursión en cálculo lambda
Y = (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))
la segunda parte es la función factorial hecho definido recursivamente
fact = (lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))
Y se aplica a los hechos para formar otra expresión lambda
F = Y(fact)
que se aplica a la tercera parte, n , que se evacua al enésimo factorial
>>> n = 5
>>> F(n)
120
o equivalente
>>> (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))(5)
120
Si, por el contrario, prefieres los fibs a los hechos , puedes hacerlo también con el mismo combinador
>>> (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: f(i - 1) + f(i - 2) if i > 1 else 1))(5)
8
Bueno, no es exactamente la recursividad lambda pura, pero es aplicable en lugares, donde solo puedes usar lambdas, por ejemplo, reducir, mapear y enumerar comprensiones u otras lambdas. El truco es beneficiarse de la comprensión de la lista y el alcance del nombre de Python. El siguiente ejemplo atraviesa el diccionario por la cadena de claves dada.
>>> data = {''John'': {''age'': 33}, ''Kate'': {''age'': 32}}
>>> [fn(data, [''John'', ''age'']) for fn in [lambda d, keys: None if d is None or type(d) is not dict or len(keys) < 1 or keys[0] not in d else (d[keys[0]] if len(keys) == 1 else fn(d[keys[0]], keys[1:]))]][0]
33
La lambda reutiliza su nombre definido en la lista expresión de comprensión (fn). El ejemplo es bastante complicado, pero muestra el concepto.
Esta respuesta es bastante básica. Es un poco más simple que la respuesta de Hugo Walter:
>>> (lambda f: f(f))(lambda f, i=0: (i < 10)and f(f, i + 1)or i)
10
>>>
La respuesta de Hugo Walter:
(lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10)
La única forma en que se me ocurre hacer esto equivale a darle un nombre a la función:
fact = lambda x: 1 if x == 0 else x * fact(x-1)
o alternativamente, para versiones anteriores de python:
fact = lambda x: x == 0 and 1 or x * fact(x-1)
Actualización : usando las ideas de las otras respuestas, pude ajustar la función factorial en una sola lambda sin nombre:
>>> map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), range(10))
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
¡Así que es posible, pero no realmente recomendado!
No puedes hacerlo directamente, porque no tiene nombre. Pero con una función auxiliar como el Y-combinator apuntado a Lemmy, puede crear recursividad pasando la función como un parámetro a sí mismo (por extraño que parezca):
# helper function
def recursive(f, *p, **kw):
return f(f, *p, **kw)
def fib(n):
# The rec parameter will be the lambda function itself
return recursive((lambda rec, n: rec(rec, n-1) + rec(rec, n-2) if n>1 else 1), n)
# using map since we already started to do black functional programming magic
print map(fib, range(10))
Esto imprime los primeros diez números de Fibonacci: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
,
Nunca he usado Python, pero this es probablemente lo que estás buscando.
Para esto podemos usar los combinadores de punto fijo , específicamente el combinador Z
, porque funcionará en lenguajes estrictos, también llamados lenguajes ansiosos:
const Z = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)))
Defina la función de fact
y modifíquela:
1. const fact n = n === 0 ? 1 : n * fact(n - 1)
2. const fact = n => n === 0 ? 1 : n * fact(n - 1)
3. const _fact = (fact => n => n === 0 ? 1 : n * fact(n - 1))
Darse cuenta de:
hecho === Z (_fact)
Y úsala:
const Z = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)));
const _fact = f => n => n === 0 ? 1 : n * f(n - 1);
const fact = Z(_fact);
console.log(fact(5)); //120
Ver también: Combinadores de punto fijo en JavaScript: Memorizar funciones recursivas
Sí. Tengo dos maneras de hacerlo, y una ya estaba cubierta. Esta es mi manera preferida.
(lambda v: (lambda n: n * __import__(''types'').FunctionType(
__import__(''inspect'').stack()[0][0].f_code,
dict(__import__=__import__, dict=dict)
)(n - 1) if n > 1 else 1)(v))(5)
Si fueras realmente masoquista, podrías hacerlo usando extensiones C, pero para repetir el eco de Greg (¡hola Greg!), Esto excede la capacidad de una función lambda (sin nombre, anónima).
No. (para la mayoría de los valores de no).
sin reducir, mapa, llamado lambdas o python internal:
(lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10)
def recursive(def_fun):
def wrapper(*p, **kw):
fi = lambda *p, **kw: def_fun(fi, *p, **kw)
return def_fun(fi, *p, **kw)
return wrapper
factorial = recursive(lambda f, n: 1 if n < 2 else n * f(n - 1))
print(factorial(10))
fibonaci = recursive(lambda f, n: f(n - 1) + f(n - 2) if n > 1 else 1)
print(fibonaci(10))
Espero que sea útil para alguien.