Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for ¿Lucas, Fibo, que hacéis con una Pytón?
Baltasar García Perez-Schofield
Baltasar García Perez-Schofield

Posted on • Edited on

     

¿Lucas, Fibo, que hacéis con una Pytón?

Recientemente he aprendido que existe una sucesión muy "parecida" a la famosísimasucesión de Fibonacci: se trata de lasucesión de Lucas.

Lasucesión de Fibonacci se obtiene comenzando con 0 y 1, y para los siguientes números, simplemente se suman los dos anteriores:

0, 1, 1, 2, 3, 5, 8, 13, 21...
Enter fullscreen modeExit fullscreen mode

Lasucesión de Lucas se obtiene comenzando con 2 y 1, y al igual que con la sucesión de Fibonacci, se suman las dos posiciones anteriores para cada nueva posición.

2, 1, 3, 4, 7, 11, 18, 29, 47...
Enter fullscreen modeExit fullscreen mode

Si lo implementamos en Python, tendremos dos funciones muy similares:

"""Sucesión de Lucas.   :param n: La posición del número a calcular.   :return: Una lista con las n primeras posiciones de Lucas."""lucas=lambdan: \[]ifn<0else \[2]ifn==0else \[2,1]ifn==1else \(l_lucas:=lucas(n-1))+[l_lucas[-1]+l_lucas[-2]]"""Sucesión de Fibonacci.   :param n: La posición del número a calcular.   :return: Una lista con las n primeras posiciones de Fibonacci."""fibo=lambdan: \[]ifn<0else \[0]ifn==0else \[0,1]ifn==1else \(l_fibo:=fibo(n-1))+[l_fibo[-1]+l_fibo[-2]]
Enter fullscreen modeExit fullscreen mode

Para obtener las listas con las sucesiones empleamos lambdas, la expresiónif, y el nuevooperador de asignación, de manera que solo tengamos que calcular la lista anterior una sola vez.

En el enlace anterior puedes aprender sobre este operador, solo tienes que bajar casi hasta el final.

Como ya sabemos, la forma de trabajar con lambdas es emplear la recursividad cada vez que queramos algo parecido a un bucle. La recursividad solo funciona si tenemos un caso base (las dos posiciones inicialesn == 0 yn == 1), y un caso normal (el resto de posiciones paran > 1).

Añadimos un caso base "extra" (n < 0), por si se da el caso de algún usuario "travieso".

La forma de generar ambas sucesiones es muy similar. Para ambas tenemos dos valores iniciales, que deben ser devueltos si intentamos obtener las dos primeras posiciones: es decir, la 0 y la 1.

A partir de ahí, simplemente concatenamos la lista anterior con la suma de las posiciones última y penúltima de dicha lista.

De hecho... son demasiado parecidas... ¿no podríamos crear una función única, que tomase como parámetro las dos primeras posiciones de la sucesión a generar? Ya de paso, ¿podemos crear una función a la que se le pasen lasn primeras posiciones de la lista inicial de una sucesión para generar los números de Lucas, de Fibonacci, y deTribonacci?

Veamos, la funciónsucc() solo hay que devolver, dada una lista iniciall_init y su número de posicioneslen_l_init...

  • paran < 0, la lista vacía,[]
  • paran < i, la listal_init hastan + 1 (porque los índices en Python comienzan en 0):l_init[:n + 1]
  • para el resto de casosn >= len_l_init,
    • se calcula la lista parasucc(n - 1), y se calcula el nuevo elemento, que es el resultado de sumar laslen_l_init últimas posiciones.

Pues ya lo tenemos. Como el código ya es más
complicado que un par de líneas, crearemos una función "de verdad".

defsucc(l_init,n):"""        Sucesión genérica.        :param l: La lista inicial de valores.        :param n: La posición del número a calcular.        :return: Una lista con las n primeras posiciones de Lucas, Fibonacci o Tribonacci."""len_l_init=len(l_init)toret=[]matchn:case_ifn<0:toret=[]case_ifn<len_l_init:toret=l_init[:n+1]case_:# Sucesión hasta la posición anteriortoret=succ(l_init,n-1)# Calcula la nueva posicióntoret+=[sum(toret[-len_l_init:])]returntoret
Enter fullscreen modeExit fullscreen mode

¡Python mola!

Estamos empleando la nueva estructura depattern matching, que, para que nos entendamos, hablando mal y rápido es comoswitch en C, pero mucho más potente. Aquí solo empleamos una fracción de sus capacidades, concretamente le añadimos condiciones a las etiquetas de los primeros dos casos. Sustituimos el nombre de lo que sería la nueva variable por _ porque en realidad, no nos interesa, ya lo tenemos enn.

Utilicemos el código:

defmain():foriinrange(-1,10):print(f"Succ Fibo -{succ([0,1],i)=}")print()foriinrange(-1,10):print(f"Succ Lucas -{succ([2,1],i)=}")if__name__=="__main__":main()
Enter fullscreen modeExit fullscreen mode

Y efectivamente, el resultado es:

ucc Fibo - succ([0, 1], i)=[]Succ Fibo - succ([0, 1], i)=[0]Succ Fibo - succ([0, 1], i)=[0, 1]Succ Fibo - succ([0, 1], i)=[0, 1, 1]Succ Fibo - succ([0, 1], i)=[0, 1, 1, 2]Succ Fibo - succ([0, 1], i)=[0, 1, 1, 2, 3]Succ Fibo - succ([0, 1], i)=[0, 1, 1, 2, 3, 5]Succ Fibo - succ([0, 1], i)=[0, 1, 1, 2, 3, 5, 8]Succ Fibo - succ([0, 1], i)=[0, 1, 1, 2, 3, 5, 8, 13]Succ Fibo - succ([0, 1], i)=[0, 1, 1, 2, 3, 5, 8, 13, 21]Succ Fibo - succ([0, 1], i)=[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]Succ Lucas - succ([2, 1], i)=[]Succ Lucas - succ([2, 1], i)=[2]Succ Lucas - succ([2, 1], i)=[2, 1]Succ Lucas - succ([2, 1], i)=[2, 1, 3]Succ Lucas - succ([2, 1], i)=[2, 1, 3, 4]Succ Lucas - succ([2, 1], i)=[2, 1, 3, 4, 7]Succ Lucas - succ([2, 1], i)=[2, 1, 3, 4, 7, 11]Succ Lucas - succ([2, 1], i)=[2, 1, 3, 4, 7, 11, 18]Succ Lucas - succ([2, 1], i)=[2, 1, 3, 4, 7, 11, 18, 29]Succ Lucas - succ([2, 1], i)=[2, 1, 3, 4, 7, 11, 18, 29, 47]Succ Lucas - succ([2, 1], i)=[2, 1, 3, 4, 7, 11, 18, 29, 47, 76]
Enter fullscreen modeExit fullscreen mode

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Lecturer in programming since 1998
  • Location
    Spain
  • Work
    Associate professor at University of Vigo
  • Joined

More fromBaltasar García Perez-Schofield

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp