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

Do you need help?

non riesco a duplicare una matrice e modificare il duplicato senza modificare anche l'originale

M
Mpinaz (270 points)
2 2 3
in HW8 by (270 points)
per la ricorsione copio la matrice iniziale e lavoro sulla copia per trovare tutti i possibili finali solo che quando copio la board iniziale e modifico la copia che ho creato mi modifica anche la board iniziale

non so come fare per mantenere la board iniziale fissa e modificare solo la copia
738 views

9 Answers

V
ValerioZ (1140 points)
0 2 6
by (1.1k points)
duplica riga per riga... altrimenti quello che succede è che copi il riferimento e si crea l'effetto collaterale di cui parli...

enjoy programming ;)
James_F (6070 points)
10 14 47
by (6.1k points)

quello che vuoi fare è una deepcopy. Il modo più banale per farlo è copiare ogni sottoarray(riga) della matrice, invece di passarlo come reference.
E.g. NON nuova = vecchia.copy() 
        MA nuova = [riga.copy() for riga in vecchia] 

anon3 (10560 points)
20 66 138
by (10.6k points)

Suggerisco di usare lo stesso metodo yes

Alegau (6770 points)
1 2 43
by (6.8k points)
Devi usare un ciclo for
Paolo Gentili (31130 points)
3 6 114
by (31.1k points)

Ti allego qui una risposta che ho dato l'altro giorno ad un problema uguale grazie a cui è stato risolto:

prova salvando in questo modo la nuova scacchiera che poi modifichi sostituendo le caselle vuote:

-Crei una nuova lista vuota (magari chiamala nuova_scacchiera)

-fai un for lista in scacchiera_vecchia

-scrivi dentro il for: nuova_scacchiera.append(lista.copy())

così non ti dovrebbe più dare problemi a tonare indietro nella ricorsione

Iacopi (870 points)
0 2 10
by (870 points)
purtroppo facendo .copy la matrice non te la copia in modo assoluto. In altre parole non è una copia "profonda" ma si vengono a creare due matrici che si riferiscono alla stessa unica, quindi modificandone una cambia anche l'altra.

Consiglio o di forzare una copia in senso profondo con un ciclo e con uno slicing, oppure di creare una matrice vuota (ad esempio con tutti zeri) e poi sostituire valore per valore.
N
Nim (3520 points)
0 2 27
by (3.5k points)
edited by
Così per divertimento

return list(map(list, mat))
return list(map(lambda l: l.copy(), mat))
return [[mat[i][j] for j in range(len(mat[0]))] for i in range(len(mat))]
return [l.copy() for l in mat]
Marco Casu (2770 points)
6 10 24
by (2.8k points)
Ti consiglio di vederti il concetto di "Shallow copy", per creare una copia di una matrice, del tutto nuova e non correlata a quella precedente, dovrai fare due iterazioni ( list comprehension ).
a
andreannn (2720 points)
5 14 34
by (2.7k points)
Ciao,

cerco di darti una risposta che riassuma quanto già detto e che spieghi cosa avviene all’interno della memoria del calcolatore.

Una matrice è una lista di liste.

Quando tu copi la matrice, lo fai inmagino con la funzione built-in “copy()” oppure con lo slicing “[:]”.

Entrambi questi metodi hanno però un problema.

In generale, quando crei la copia di una lista, quello che succede è che si crea una nuova lista in una posizione di memoria diversa dalla prima, e vengono poi copiati i contenuti all’interno della seconda.

Quando però hai una lista di liste, la lista più grande (cioè quella che contiene le altre liste) viene effettivamente copiata in un’altra posizione di memoria, ma quando poi si va a copiare il contenuto, che in questo caso sono liste, rimangono con la loro posizione di memoria iniziale. Questo significa che quando modificherai le liste all’interno della lista copiata, starai modificando anche le liste di partenza (cioè il contenuto della matrice iniziale.

Per ovviare a questo problema, il metodo più veloce sarebbe utilizzare la funzione deepcopy() che però sfortunatamente non è built-in e andrebbe importata. Poiché noi non possiamo importare nulla, ti scrivo cosa fa questa funzione.

In realtà è molto semplice

basta creare un ciclo for che copi ogni elemento della matrice iniziale.

L = [] #inizializzi una lista

for lista in matrice_iniziale:

#aggiungi ciascun elemento all’interno della lista inizializzata sopra

dopo questo ciclo L sarà una deep- copia , ossia una copia che non ti darà più alcun problema.

Anche a me si era presentato questo errore e mi ha portato via mezz’ora :) Spero possa averti aiutato.
aa91 (3450 points)
6 14 46
by (3.5k points)

@Mpinaz mi permetto solo di dirti, a fronte delle numerose e valide risposte ricevute, che se hai trovato la risposta e soluzione al tuo problema di segnarla come Best Answer ;)