0% encontró este documento útil (0 votos)
193 vistas

Python - Funciones Recursivas

El documento describe el uso de funciones recursivas y generadoras en Python. Explica que las funciones recursivas se llaman a sí mismas y son útiles para resolver algunos problemas en lugar de iteraciones. También describe cómo las funciones generadoras producen secuencias de valores de forma iterativa usando la palabra clave "yield". Incluye ejemplos de funciones recursivas y generadoras para sumar cubos, contar números de Fibonacci y generar secuencias infinitas.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
193 vistas

Python - Funciones Recursivas

El documento describe el uso de funciones recursivas y generadoras en Python. Explica que las funciones recursivas se llaman a sí mismas y son útiles para resolver algunos problemas en lugar de iteraciones. También describe cómo las funciones generadoras producen secuencias de valores de forma iterativa usando la palabra clave "yield". Incluye ejemplos de funciones recursivas y generadoras para sumar cubos, contar números de Fibonacci y generar secuencias infinitas.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 13

1

6.9 Funciones recursivas

Una función puede llamarse a si misma. Estas funciones se denominan recursivas. El uso
de la recursón es una técnica útil en programación para resolver algunos problemas en
sustitución de los métodos iterativos con for o while. La recursión construye la solución
Ilamándose a si misma, usualmente mediante una estructura if.

La recursión realiza un ciclo internamente, por lo tanto, la programación ya no requiere


escribir ciclos. Sin embargo, la recursión debe usarse con precaución pues puede ser
costosa en tiempo computacional especialmente si cada Ilamada genera más de una
Ilamada a la misma función. Adicionalmente, los lenguajes de programación tienen un
límite máximo para las llamadas recursivas.

Ejemplo. Escribir una función para sumar los cubos de los primeros n números naturales.

sc(n) = 13 + 23 + 33 + ... + (n-1)3 + n3

La manera usual de interpretar esta suma es mediante una repetición en la cual en cada
ciclo se agrega un nuevo término, como se muestra a continuación:

del sc(n):
Otra manera de interpretar esta suma es mediante una definición

for iesinla suma:


recurrente: Si sc(n) 13 + 23 + 33 + ... + (n-1)3 + n3
range(1,n+1):
Entonces sc(n-1) es: r=r+i**3
13 + 23 + 33 + ... + (n-1)3

Y se puede escribir:

sc(n) = sc(n-1) + n3

Esta definición requiere una regla para que la invocación no continue indefinidamente
hacia atrás. Entonces, la definición completa es:

sc(n — 1) + n3 , n > 1
sc(n) = 1, n=1

Esta regla se puede aplicar manualmente como en el siguiete caso:

3 3 3 3
sc(4) = sc(3) + 43 = sc(2) + 33 + 4 = sc(1) + 23 + 3 + 43 = 1 + 2 + 3 + 4^ = 100

El lenguaje Python permite traducir e instrumentar funciones recursivas.

Python
2

Ejemplo. Escribir en Python una función recursiva para calcular la suma de los cubos de
los primeros n números naturales usando la definición anterior.

Se la almacenará en un módulo con el mismo nombre

def sc(n):
Prueba de las funciones.
if n›1: Ambas versiones producen el mismo resultado
r=sc(n-1)+n**3
» from sc else:
import sc
»› r=sc(4) r=
1
100

NOTA: La recursión es realizada internamente por el traductor mediante llamadas


recurrentes de manera similar a su aplicación manual. El lenguaje Python tiene un límite
para las llamadas recursivas internas. En la versión 3.4.1 para este ejemplo es cercano a
1000.

Ejemplo. Escribir una función recursiva para contar en cuantos intentos se puede
adivinar el número de un dado.

from random import * def adivina(intento):


n=randint(1,6) x=int(input( if x!=n:
print(
intento=intento+1 adivina(intento)
else:
))
print(

Prueba desde la ventana interactiva


» from adivina import adivina
» adivina(1) Se inicia la función en el intento 1
Adivina el número: 5
Fallaste: intenta otra vez
Adivina el número: 4
Fallaste: intenta otra vez
Adivina el número: 6
Acertaste en 3

Python
3

Ejemplo. Escribir una función recursiva con el nombre fib para obtener el n-ésimo término de
la secuencia de Fibonnaci.
n: 1, 2, 3, 4, 5, 6, 7, 8, 9, ...
fib(n): 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

Instrumentación
Nombre de la función: fib

En la secuencia se puede observar que cada término de fib(n) es igual a la suma de los
dos términos anteriores: fib(n) = fib(n-2) + fib(n-1) para n>2. Mientras que el resultado es
fib(n) = 1 para n=1 y n=2.

Prueba dedel-
la función
f-ib(n):en la ventana interactiva
if n==1 or
» from fib import n==2:fib
» fib(6) return 1
8 else:
» fib(2) return fib(n-2)+fib(n-1)
1
» fib(9)
34
» fib(25)
75025

En este ejemplo, la recursión es muy costosa computacionalmente pues cada Ilamada a la


función produce dos nuevas llamadas recurrentes y la secuencia de llamadas se abre en
ramificaciones rápidamente. Se Ilega muy pronto al límite máximo de llamadas recursivas
permitidas. La ejecución es ineficiente pues cada Ilamada requiere tiempo computacional

Ejemplo.

fib(6) = fib(4) + fib(5)


= fib(2) + fib(3) + fib(3) + fib(4)
= 1 + fib(1) + fib(2) + fib(1) + fib(2) + fib(2) + fib(3)
= 1 + 1 + 1 + 1 + 1 + 1 + fib(1) + fib(2)
=1+1+1+1+1+1+1+1
=8

La recursión debe ser usada con precaución y debe evitarse cuando la función genera
más de una Ilamada a si misma en cada invocación, como en el ejemplo anterior:

Python
4

6.10 Funciones generadoras

Una función generadora es una función especial para producir una secuencia de valores

Para entender este concepto se desarrolla un ejemplo. Suponer que se necesita una Iista
de los cubos de los números naturales

La siguiente es una función elemental típica que recibe un entero y entrega su cubo. Estas
funciones se limitan a entregar solamente un valor:

La funcióndef- cubo(n):
se puede Ilamar dentro de una instrucción de repetición para obtener
c=n**3
sucesivamente cada resultado:
return
Prueba del programa
from cubo import
cubo for n in
range(5):
1 c=cubo(
8 n)
27
64

Una manera diferente de enfocar la solución para este pequeño problema es producir
dentro de la función la Iista de valores para que sean entregados uno a la vez sin
necesidad de Ilamar a la función dentro de una repetición. Este dispositivo se denomina
función generadora

Una función generadora usa la palabra especial yield para entregar uno por uno los
valores de la secuencia. Mediante la función especial next o el operador in se pueden
solicitar sucesivamente cada valor de la secuencia.

Ejemplo. Defina una función generadora para producir la secuencia de n cubos

def cubo(n):
for i in range(n):
c=i**3
yield c

Python
5

Activación de la función generadora de cubos en la ventana interactiva


›>› from cubo import cubo
» c=cubo(5) Inicia el generador
» print(next(c)) La función next solicita el siguiente valor

» print(next(c))
1
» pr1nt (next(c)
)8
» pr1nt (next(c)
) 27
» print(next(c))
64
» print (next(c) )

StopIteration

Un programa para obtener cada valor de la secuencia creada por la función generadora
cubo usando next

from
Prueba del cubo import cubo
programa
c=cubo(5)
for i in range(5):
1 print(next(c))

27
64

También se puede solicitar cada valor mediante el operador in que implícitamente usa
next para obtener el siguiente valor de la secuencia.

from
Prueba del cubo import cubo
programa
for c in cubo(5):
print(c)
1
8
27

Python
6

64

Los generadores actúan de manera diferente a las funciones normales. Una función
normal es Ilamada para entregar cada resultado. Esta Ilamada puede estar dentro de una
repetición para obtener el resultado. Por otra parte, la función generadora produce una
secuencia pero solo entrega un valor a la vez y debe ser activada sucesivamente en forma
explícita con next o en forma implícita con el operador in para obtener cada uno de los
siguientes valores.

6.10.1 Generadores infinitos

El concepto de función generadora permite definir generadores infinitos

Ejemplo. Definición de un generador infinito de cubos:

El siguiente
defprograma
cubo():usa el generador infinito con next para generar 10 cubos:
n=0
Prueba del programa
fromwhile
cubo True:
import cubo
c=cubo( ) c=n**3
Por :í inyieldrange(1ej:
8 printc (next(c ))
27
64
125
216
343
512
729

Python
7

Un programa que usa el generador infinito con in necesita interrumpir la secuencia:

Prueba del programa


from cubo import cubo
for c in cubo():
1
print(c)
if c›300:
8
break
27
64
125
216
343

Desde la ventana interactiva


›>› from cubo import cubo
» for c in cubo():
print (c)

1
8
27
64
125
216
343
512
729 Se necesita interrumpir la secuencia infinita presionando las teclas Ctrl C

Ejemplo. Generador infinito de números primos

def primo():
n=0
while True:
n=n
+1
c=0
Por d in range(2,
n): if n%d==6:
c=c+1
if c==0:

Python
8

El siguiente programa usa next para generar 10 números primos

from primo import primo


1
c=primo()
2
for i in
3
range(10):
5
print(next(c
7
11
13
17
19
23

El siguiente programa que usa el generador infinito con in necesita interrumpir la


secuencia:

from primo import


1
primo for c in
2
primo():
3
pr:int (c)
5
if c›18:
7
11

Python
9

Ejemplo. Generador infinito de la secuencia de Fibonacci

def f1b():
a, b = -1, 1
while True:
1 c = a + b
1 yield c
2 a, b = b, c
3
5
8
from fib import
fib c=fib()
for i in
range(7):

Python
10

6.10.2 Interrupción de un ciclo doble

Una función generadora permite definir un dispositivo para interrumpir de manera elegante
un ciclo doble:

Ejemplo. Suponer que se desea encontrar el primer caso en el que los valores i, j
cumplen la condición:

2i 3
+ 3j 2 es divisible para 7, para i, j = 1, 2, 3, ... ,9

En el siguiente programa, la instrucción break solamente interrumpe las repeticiones del


ciclo en el que se ejecuta la instrucción break, en este caso el ciclo interno:

Prueba del programa


for i in range(1,1d):
for j in
1 2 14 range(1,10):
2 2 28 n=2*i**3+3*j**2
4 2 140 if n%7==0:
7 7 833 print(i,j,n)
8 2 i036
9 2 1470

La estrategia para salir de ambos ciclos es convertirlos en un solo ciclo. Para esto se
escribe una función generadora que produce una nueva pareja de índices 1, j cada vez
que es Ilamada la función. En este caso, la instrucción break al interrumpir un ciclo, es
equivalente a interrumpir los dos ciclos incluidos en el programa anterior.

Prueba del
defprograma
rango_doble(n,m):
for i in
1 2 14 range(1,n):
for j in
range(1,m):
yield [i,j]

for i,j in rango_doble(10,10):


n=2*i**3+3*j**2
if n%7==0:
print(i,j,

Python
11

6.11 Funciones con parámetros de tipo función

Para algunas aplicaciones, especialmente matemáticas, es útil enviar una función como
parámetro para otra función.

Ejemplo. Defina una función para sumar n ordenadas de una función f(x) para valores
de x espaciados regularmente en el intervalo cerrado [a, b]

Datos
f: Función (ingresa como
parámetro) a,b: Límites
n: Cantidad de puntos (mayor que 1)

Resultado
s: Suma de ordenadas
Fórmula para calcular el espaciamiento entre los valores de x:
b —a
h-
n—1

def suma(f,a,b,n):
Prueba: Calcularh=(b-a)/(n-1)
la suma 20 de ordenadas de f(x)=x sen(x) para valores de x espaciados
en forma regulars=0
en el intervalo [0, 2]:
for i in
» from math import*
range(n):
» from suma import*
s=s+f(a+i*h)
» def f(x):
y=x*sin(x)
ret urn y
»> s=suma(f,0,2,20)
ȴ S
17. 455091419917455

Python
17

6.13 Ejercicios con funciones

1. Escriba una función conteo(n) que entregue la cantidad de divisores enteros positivos
que tiene un número entero dado n. Escriba un programa de prueba que use la
función escrita para encontrar cual número entre 1 y 100 tiene más divisores enteros.

2. Escriba un programa de prueba que use la función primo y encuentre dos números
enteros aleatorios menores que 100 tales que su suma sea también un número primo.

3. Escriba una función perfecto(n) que determine si un número entero dado n es un


número perfecto. Un número perfecto debe ser igual a la suma de todos sus divisores
enteros menores que el valor del número.
Ejemplo: 28 = 1 + 2 + 4 + 7 + 14
Escriba un programa de prueba que use la función escrita y encuentre los números
perfectos entre 1 y 1000

4. Escriba una función sumad(n) que entregue la suma de las cifras de un número dado n.
Con esta función escriba un programa que genere 10 números aleatorios entre 1 y 100 y
encuentre cual de ellos tiene la mayor suma de sus cifras.

5. Escriba una función cuad(n) que determine si el cuadrado de un número natural n dado,
es igual a la suma de los primeros n números impares.
Ej. 62 = 1+3+5+7-›9-r11
Escriba un programa de prueba que ingrese un dato desde el teclado, use la función y
muestre el resultado en la pantalla.

6. Escriba una función secuencia1(n) que entregue el n-ésimo término de la siguiente


secuencia, en la cual cada término, a partir del tercero se obtiene sumando los dos
anteriores: 1, 1, 2, 3, 5, 8, 13, 21, .... Escriba un programa de prueba que ingrese un dato
desde el teclado use la función y muestre el resultado en la pantalla.

7. Escriba una función secuencia2(n) que entregue el n-ésimo término de la siguiente


secuencia, en la cual cada término, a partir del cuarto se obtiene sumando los tres
anteriores: 1, 1, 1, 3, 5, 9, 17, 31, 57, ..... Escriba un programa de prueba que ingrese un
dato desde el teclado, use la función y muestre el resultado en la pantalla.

8. Escriba una función sim(x) que reciba un entero y determine si es simétrico, es decir si
los dígitos opuestos alrededor del centro son iguales. Escriba un programa de prueba que
genere números aleatorios entre 1 y 10000 hasta obtener un número que sea simétrico

9. Escriba una función aIfin(n) que entregue como resultado la cantidad de veces que
debe lanzarse un dado hasta que salga un número n dado como parámetro. Escriba un
programa de prueba que ingrese un dato desde el teclado, use la función y muestre el
resultado en la pantalla.

10. Escriba una función conteo(x) que determine la cantidad de términos que deben
sumarse de la serie: 1“2”3 + 2“3*4 + 3*4*5 + 4”5*6+.......hasta que la suma exceda a
un
valor x dado. Escriba un programa de prueba que genere un número aleatorio para x entre
1 y 1000, use la función y muestre el resultado en la pantalla.

Python
18

11. Escriba una función fact(n) que reciba un numero entero n y devuelva su factorial.
Escriba un programa de prueba que genere un número aleatorio entero k entre 1 y 10. Use
la función y muestre la suma de los factoriales de los primeros k números naturales

12. Escriba una función sumadiv(n) que reciba un número entero n y devuelva la suma de
sus divisores. Escriba un programa de prueba que ingrese un dato desde el teclado, use
la función y muestre el resultado en la pantalla

13. Escriba una librería o módulo con el nombre convertir que contenga dos funciones:
[r,t]=polar(x, y) Recibe las coordenadas cartesianas x,y y entrega las
coordenadas polares r, t
[x,y]-cartesiana(r, t) Recibe las coordenadas polares r, t y entrega las
coordenadas cartesianas x, y
Formulación: r = x2 + y2 , t = arctan(y/x), x = r cos(t), y = r sen(t)
Escriba un programa con un menú que tenga tres opciones en un ciclo interactivo:
1) Convertir a polares
2) Convertir a cartesianas
3) Salir
Según la opción elegida, el programa pide los datos, llama a la función respectiva y
muestra en pantalla los resultados.

14. El siguiente es un algoritmo para generar un número aleatorio entero (seudo aleatorio)
1) Dado un número entero x
2) Sume los cuadrados de los dígitos del número. Este resultado es el número
aleatorio
a) Escriba una función c=aIeatorio(x) que entregue el resultado producido.
b) Escriba un programa que lea un valor inicial para x y Ilame a la función aleatorio
repetidamente, enviando como nuevo dato, el resultado que entrega la función.
Determine cuantas veces hay que Ilamar a la función aleatorio hasta que el
resultado sea igual a algún valor que ya salió anteriormente. Esta cantidad se
denomina longitud de la secuencia aleatoria

15. La siguiente definición recursiva produce el máximo común divisor entre dos números
enteros positivos. Escriba y pruebe una función con esta definición
mcd(a -b,b), a> b
mcd(a,b)= mcd(a,b -a), b> a
a, a=b

16. Analice la siguiente definición recursiva para determinar cuantos dígitos tiene un
número entero. Escriba y pruebe una función. Note el uso de la división entera: ll
nd( n//10 ), n Z: 10
nd n = 1, n < 10

17. Escriba una función recursiva para obtener la cantidad de dígitos impares que contiene
un número entero positivo.

18. Escriba una función recursiva para calcular la suma de los n primeros términos de la
serie:
S(n) = 1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + ...

Python

También podría gustarte