usar sintaxis propias funciones funcion español ejemplos ejemplo como python recursion lambda y-combinator

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.