Please ignore secret bonuses. Secret tests do NOT award bonus. Max hw grade is 30+2 bonus efficiency

Do you need help?

Notice Board

Per partecipare al corso di Fondamenti di programmazione 2023-24 loggatevi e attivatelo nella vostra pagina dei corsi preferiti. A quel punto il corso appare nel menù personale cliccando sul proprio avatar. Per i materiali degli anni precedenti seguite lo stesso metodo.

To join the Programming/Lab 2023-24 course, log-on and select it on the my courses page. It will appear on the personal menu of your avatar. For earlier years use the same method.

Come modificare un parametro immesso in una funzione a livello globale?

P
Powner (5600 points)
36 68 85
in Es1 by (5.6k points)

è data la funzione modi che accetta come parametro una lista ls:

def funzione(ls):

Poiché il primo esercizio richiede una modifica della lista a livello globale, incontro un problema durante l'esecuzione delle istruzioni nella funzione: la variabile ls viene modificata a livello locale (ad esempio, printando la lista prima del return verifico che sia effettivamente diversa) ma a livello globale rimane invariata, a meno che non utilizzo moduli come del ls[x] o ls.remove(). Perché istruzioni come l'assegnazione modificano la lista solo a livello locale?

879 views
closed

2 Answers

Best answer
andrea.sterbini (207920 points)
749 1267 2373
by (208k points)
selected by
La lista è mutabile, se ne modifichi gli elementi in una funzione anche il programma che l'ha passata se ne accorge.

Il nome del parametro, però, è locale, se lo riassegni in una funzione perdi il valore che conteneva, ed il valore originale rimane invariato.
P
Powner (5600 points)
36 68 85
by (5.6k points)
Non capisco come possa fare differenza a livello teorico: l'assegnazione non è anch'essa una modifica ai valori della lista?
andrea.sterbini (207920 points)
749 1267 2373
by (208k points)
No, l'assegnamento è una modifica di auale sia l'oggetto legato al nome della variabile.
Il vecchio oggetto viene sostituito e nella tabella del namespace locale al nome del parametro viene assegnato il nuovo valore.
Il vecchio valore resta però raggungibile nel codice che ha chiamato la funzione e quindi resta invariato.
P
Powner (5600 points)
36 68 85
by (5.6k points)
Capito, grazie mille!
LeonardoEmili (35740 points)
13 65 155
by (35.7k points)

Buonasera!

Probabilmente perché classifica come variabile locale, ci sono diversi approcci che puoi scegliere di prendere. Te ne elenco alcuni:

  1. Potresti lavorare con la lista e quando poi devi eliminare dei valori utilizzare i metodi da te descritti. Essi risultano particolarmente comodi se devi eliminare elementi tramite indice o tramite elemento soprattutto se ti trovi in un ciclo iterativo.
  2. Potresti anche passarlo come parametro di una 3° funzione e una volta finito di lavorare sulla lista ritornarla applicando così le modifiche a livello globale.
  3. Infine potresti ovviamente specificare tu che si tratta di una variabile globale con la keyword global, ma come sicuramente ricorderai il professore ci ha parlato che questo "sporca" lo scope del programma. Utilizza variabili globali il meno possibile.
Questi sono solo alcuni dei svariati metodi per modificare liste e altri elementi mutabili, in ogni caso ti rimando alla documentazione su Python che è a dir poco infinita!
Spero di averti aiutato,
buona serata
Leonardo Emili
P
Powner (5600 points)
36 68 85
by (5.6k points)
In realtà la mia domanda sorge proprio a causa del fatto che i metodi suddetti non mi funzionano all'interno del ciclo iterativo (è come se, eliminando elementi dalla lista su cui sto eseguendo il for, non riuscisse a completare il procedimento sugli elementi rimasti nella lista stessa). Mi riferisco ovviamente al primo approccio che mi hai suggerito
francesco.dev (33560 points)
21 51 129
by (33.6k points)
Bella risposta Leonardo!
LeonardoEmili (35740 points)
13 65 155
by (35.7k points)
Mmmm da quello che mi dici sembra che tu voglia svolgere operazioni di modifica di una lista su una stessa lista su cui stai iterando! E' corretto? (perdona i giochi di parole). In ogni caso questo non ti è permesso perché stai modificando anche la lista e quindi il programma si trova a iterare su qualcosa di variabile, il che genera un errore. Potresti utilizzare una lista di appoggio (sostanzialmente la copia della tua lista) e iterare su questa per poi modificare gli elementi dalla lista originaria! Fammi sapere
LeonardoEmili (35740 points)
13 65 155
by (35.7k points)
Grazie mille francesco :P
P
Powner (5600 points)
36 68 85
by (5.6k points)
Hai centrato esattamente il problema! Se svolgo operazioni di modifica sulla lista su cui sto iterando, mi genera errori. Al contrario, se utilizzo una lista di appoggio (ad esempio, nuovaLista) e dopo faccio ls=nuovaLista non me la modifica a livello globale.

In pratica è questo il problema su cui sto sbattendo la testa.

Ho anche provato, dopo il ciclo, a scrivere un algoritmo che scorre la lista ls nuovamente e ne elimina (con il metodo ls.remove()) ogni elemento che non si trova anche nella lista nuovaLista, ma anche questo procedimento non mi dà la lista desiderata.
andrea.sterbini (207920 points)
749 1267 2373
by (208k points)
parola chiave: slice
LeonardoEmili (35740 points)
13 65 155
by (35.7k points)
Prova così, se devi eliminare elementi: crea una lista di appoggio, itera sulla lista originale e modifica la lista di appoggio. Poi cancella l'intera lista originaria e fai una deep copy della lista di appoggio sulla lista originale, infine ritorna la lista ;)
P
Powner (5600 points)
36 68 85
by (5.6k points)
In realtà nel frattempo ho trovato una soluzione diversa: svuoto la lista ls e poi aggiungo gli elementi della lista di appoggio con un ciclo. So che non è la migliore (sicuramente lavorerò sullo slice, cercando di capire cosa possa aiutarmi per questo problema), ma per il momento ho risolto così!
LeonardoEmili (35740 points)
13 65 155
by (35.7k points)
Felice che tu abbia risolto!!