Funzione lista Fibonacci: variabile locale o parametro default

di il
6 risposte

Funzione lista Fibonacci: variabile locale o parametro default

Ciao a tutti.
Volevo scrivere una funzione ricorsiva per determinare i numeri della successione di Fibonacci.
Il mio obiettivo è che la funzione ricevendo in ingresso gli n numeri della successione che voglio visualizzare, oltre ad essere ricorsiva mi restituisca una lista contenente appunto gli ne numeri di Fibonacci.
La faccio breve e vi allego il codice che mi sembra funzioni:

def fibox(n):
    serie = [] #inizializzazione successione di Fibonacci
    if n < 1:  #nel caso si chiedano n=0 numeri della successione
        return n #la funzione restituisce 0
    if n == 1:            # si chiede il primo numero
        s1 = fibox (n-1)  # richiamo la funzione con n-1 ->s1=0 del caso n=0
        a = s1 + n        # tovo l'elemento nuovo
        serie.append(a)   # lo aggiungo alla succesione
        return serie      # restituisco la successione
    if n == 2:            # si chiede il secondo numero
        s2 = fibox(n-2)   # richiamo la funzione con n-2 -> s2=0
        s1 = fibox(n-1)   # richiamo la funzione con n-1
        a = s1[n-2] + s2  # sommo il primo numero di Fibonacci a s2=0
        s1.append(a)      # aggiungo alla successione il risultato
    if n > 2:             # nei casi in cui si chiedano n>2 numeri
        s2 = fibox(n-2)   # richiamo la funzione per n-2 numeri
        s1 = fibox(n-1)   # richiamo la funzione per n-1 numeri
        a = s1[n-2] + s2[n-3] # sommo gli ultimi elementi delle due liste
        s1.append(a)      # aggiungo alla successione il risultato
    return s1             # restituisco il risultato
Per prima cosa se avete idee migliori ovviamente suggerite pure
Tornando al mio dubbio, vorrei capire come mai definire la serie come nella seconda riga di codice non equivale a definire una funzione come segue
def fibox(n, serie = []):
e poi tutto il resto invariato!
Capisco la differenza formale ma non il fatto che, richiamando la funzione senza specificare il parametro serie, ottengo un risultato diverso da quello corretto che invece ottengo col codice riportato.
Spero di essere riuscito a spiegarmi...
ciao a tutti

6 Risposte

  • Re: Funzione lista Fibonacci: variabile locale o parametro default

    Per quanto riguarda il tuo secondo dubbio, fibox è una funzione ricorsiva, quindi ogni volta che scrivi fibox(qualcosa) stai richiamando ovviamente tale funzione, che come prima riga ha serie = [] . In pratica ad ogni chiamata di fibox corrisponde serie = [], quindi è normale che se tu metti serie = [] tra i parametri devi includerlo anche ad ogni chiamata, sennò le due cose non sono equivalenti.

    Per quanto riguarda il codice, occorre dire che l'utilità dell'implementazione ricorsiva della successione di Fibonacci è utile solo a far pratica con la ricorsione perché ha complessità esponenziale e quindi se un giorno dovesse servirti non usare mai questo approccio. Detto questo, senza stravolgere il tuo approccio io lo farei così:
    
    #!/usr/bin/python3
    
    def fibox(n):
        if n < 0:
            return -1
        if n == 0:
            return 0
        if n == 1:
            return 1
        if n == 2:
            return [1, 1]
        #se n > 2
        previous_fib = fibox(n - 1)
        return previous_fib + [previous_fib[-2] + previous_fib[-1]]
    
    a = fibox(10)
    print(a)
    
    L'indice negativo nel caso tu non l'avessi mai incontrato significa che inizia a contare gli indici da destra anziché da sinistra:

    Ad esempio:
    
    list = [1,2,3,4,5]
    print(list[-1])
    
    Stampa 5 che è il primo valore da destra.
  • Re: Funzione lista Fibonacci: variabile locale o parametro default

    @IfNoFalseTrue, se sevi dare consigli, ALMENO consiglia giusto!

    Questa e' la sequenza di Fibonacci GENERALIZZATA, con indici POSITIVI e NEGATIVI:
    
    -55, 34, -21, 13, -8, 5, -3, 2, -1, 1, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
    
    NON E' una buona cosa far si che una funzione ritorni oggetti di tipo diverso. E' meglio che ritorni sempre oggetti dello stesso tipo, altrimenti bisogna fare dei test specifici sul tipo del valore di ritorno, complicando inutilmente le rimanenti parti del codice.
    
    <0 -> []  
    0 -> [0]  OPPURE [] ma lo si deve dire
    1 -> [1]
    2 -> [1,1]
    3 -> [1,1,2]
    ...
    
  • Re: Funzione lista Fibonacci: variabile locale o parametro default

    È vero, è meglio ritornare sempre una lista in questo caso. E non ho capito cosa intendi, perché dici che questa è generalizzata?
  • Re: Funzione lista Fibonacci: variabile locale o parametro default

    Grazie mille!
    Sì mi sono chiare le vostre indicazioni!
    P.s. per quanto riguarda invece l'inserimento di serie = [] tra i paramentri della funzione, non inizializza serie = [] a ogni chiamata, ma raccoglie in pratica il valore della chiamata precedente!
  • Re: Funzione lista Fibonacci: variabile locale o parametro default

    La lista é un mutable object e quando utilizzato come valore di default viene creato alla prima chiamata, nelle chiamate successive non viene ricreato.
    Per maggiori informazioni, cerca con google "python mutable defaults".
  • Re: Funzione lista Fibonacci: variabile locale o parametro default

    candaluar ha scritto:


    La lista é un mutable object e quando utilizzato come valore di default viene creato alla prima chiamata, nelle chiamate successive non viene ricreato.
    Per maggiori informazioni, cerca con google "python mutable defaults".
    Ecco! Grazie mille! Questa è la spiegazione di chi ha studiato
    io ero arrivato a questa conclusione più o meno mettendo un print di prova dopo ogni chiamata di ricorsione...
    Perfetto grazie ancora!
Devi accedere o registrarti per scrivere nel forum
6 risposte