2012-03-14 10 views
25

Eventuali duplicati:
Python: How do I pass a variable by reference?Python: quando una variabile passa per riferimento e quando per valore?

Il mio codice:

locs = [ [1], [2] ] 
for loc in locs: 
    loc = [] 

print locs 
# prints => [ [1], [2] ] 

Perché loc non di riferimento di elementi di locs?

Python: Tutto viene passato come riferimento se non è stato copiato esplicitamente [Non è vero? ]

Spiegare per favore ... come decide python fare riferimento e copiare?

Aggiornamento:

Come fare?

def compute(ob): 
    if isinstance(ob,list): return process_list(ob) 
    if isinstance(ob,dict): return process_dict(ob) 

for loc in locs: 
    loc = compute(loc) # What to change here to make loc a reference of actual locs iteration ? 
  • locs devono contenere la risposta finale trasformati!
  • Non voglio usare enumerate, è possibile senza di esso?
+4

Tutto è passato per valore, ma ogni valore è solo un riferimento;) – wim

risposta

17

Tutto in Python viene passato e assegnato in base al valore, nello stesso modo in cui tutto viene passato e assegnato in base al valore in Java. Ogni valore in Python è un riferimento (puntatore) a un oggetto. Gli oggetti non possono essere valori. L'assegnazione copia sempre il valore (che è un puntatore); due di questi indicatori possono quindi puntare allo stesso oggetto. Gli oggetti non vengono mai copiati a meno che tu non stia facendo qualcosa di esplicito per copiarli.

Per il tuo caso, ogni iterazione del ciclo assegna un elemento della lista alla variabile loc. Quindi si assegna qualcos'altro alla variabile loc. Tutti questi valori sono indicatori; stai assegnando dei puntatori; ma non intacca alcun oggetto in alcun modo.

+0

Secondo il mio punto di vista, l'hai descritto come il migliore. Dimmi solo la risposta dell'aggiornamento alla domanda: quella parte che ti sei perso. –

+0

Quindi cosa succede allora con numeri interi e float? Sono solo considerati oggetti immutabili? Come fa Python a gestirlo, poiché sono sicuro che non può contenere tutti i numeri immaginabili in memoria pronti per essere referenziati. –

+0

@AndrewS: Integer e float sono infatti immutabili (dovrebbe essere evidente che non hanno metodi che si mutano da soli). Non sono sicuro di cosa significhi la seconda parte del tuo commento. – newacct

2

Tutto è passato per oggetto. Il rebinding e il mutating sono operazioni differenti.

locs = [ [1], [2] ] 
for loc in locs: 
    del loc[:] 

print locs 
3

Quando si dice

loc = [] 

si sta rebinding la variabile loc ad una lista vuota appena creata

Forse si vuole

loc[:] = [] 

che assegna una fetta (il che accade essere l'intera lista) di loc alla lista vuota

+1

Credo che questo ultimo esempio sia quello che OP stava cercando! –

7

Non aiuta in Python a pensare in termini di riferimenti o valori. Né è corretto.

In Python, le variabili sono solo nomi. Nel ciclo for, loc è solo un nome che punta all'elemento corrente nell'elenco. Fare loc = [] semplicemente ricollega il nome loc a un elenco diverso, lasciando la versione originale da solo.

Ma dal momento che nel tuo esempio, ogni elemento è una lista, è possibile mettere in mutare quell'elemento, e che sarebbero riflesse nella lista originale:

for loc in locs: 
    loc[0] = loc[0] * 2 
+2

Potrebbe essere utile leggere * Idiomatic Python * - ["altri linguaggi hanno variabili, Python ha etichette."] (Http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other -languages-have-variables) Anche il resto è una buona lettura. ;) –

+0

Come modificare ciascun elemento del contenitore? \ –

+0

@Yugal quale parte di ciò che ho scritto sopra non era chiara? –

44

Effbot (aka Fredrik Lundh) ha descritto Lo stile di passaggio delle variabili di Python come call-by-object: http://effbot.org/zone/call-by-object.htm

Gli oggetti sono allocati nell'heap e i puntatori possono essere passati ovunque.

  • Quando si effettua un incarico come x = 1000, una voce del dizionario viene creata che mappa la stringa "x" nello spazio dei nomi corrente a un puntatore all'oggetto intero contenente mille.
  • Quando si aggiorna "x" con x = 2000, viene creato un nuovo oggetto intero e il dizionario viene aggiornato per puntare al nuovo oggetto. Il vecchio oggetto mille è invariato (e può o non può essere vivo a seconda che qualcun altro faccia riferimento all'oggetto).
  • Quando si esegue una nuova assegnazione come y = x, viene creata una nuova voce di dizionario "y" che punta allo stesso oggetto della voce per "x".
  • Gli oggetti come stringhe e numeri interi sono immutabili. Ciò significa semplicemente che non ci sono metodi che possono modificare l'oggetto dopo che è stato creato. Ad esempio, una volta creato l'intero numero mille, non cambierà mai. La matematica viene eseguita creando nuovi oggetti interi.
  • Gli oggetti come gli elenchi sono modificabili. Ciò significa che il contenuto dell'oggetto può essere modificato da qualsiasi cosa che punta all'oggetto. Ad esempio, x = []; y = x; x.append(10); print y stamperà [10]. La lista vuota è stata creata. Sia "x" che "y" puntano alla stessa lista. Il metodo accoda il metodo muta (aggiorna) l'oggetto elenco (come l'aggiunta di un record a un database) e il risultato è visibile sia a "x" che a "y" (proprio come un aggiornamento del database sarebbe visibile a ogni connessione a quel database).

Speranza che chiarisca il problema per voi.

+1

risposta eccellente. – sunqiang

2

Perché la località non è un riferimento di elementi di loc?

È. O almeno, è nello stesso senso che ogni altra variabile in Python è. Le variabili Python sono nomi , non memoria. loc è un nome utilizzato per fare riferimento agli elementi di [[1,2], [3,4]], mentre locs è un nome che fa riferimento all'intera struttura.

loc = [] 

Questo non significa "guardare la cosa che loc nomi, e indurlo a trasformare in []". È non possibile significa che, perché gli oggetti Python sono non in grado di di una cosa del genere.

Invece, significa "causa loc di smettere di essere un nome per la cosa che è attualmente un nome per, e inizia invece ad essere un nome per []". (Ovviamente, indica lo specifico [] fornito, poiché in generale potrebbero esserci più oggetti in memoria uguali.)

Come risultato, il contenuto di locs rimane invariato.

Problemi correlati