2016-04-03 11 views
5

Non sono in grado di capire cosa sta succedendo qui. Il riferimento in appendice alla funzione range è una sorta di creazione di un elenco ricorsivo all'indice 3.Quale funzione di intervallo fa a un elenco Python?

>>> x = range(3) 
[0, 1, 2] 
>>> x.append(x) 
[0, 1, 2, [...]] 
>>> x[3][3][3][3][0] = 5 
[5, 1, 2, [...]] 

considerando che, quando provo questo:

>>> x = range(3) 
[0, 1, 2] 
>>> x.append(range(3)) 
[0, 1, 2, [0, 1, 2]] 

posso facilmente dedurre il motivo per il secondo caso, ma non è in grado di capire ciò che aggiungendo riferimento alla funzione di range sta facendo alla lista allegata.

+3

perché è questo ha taggato sia Python 2 e 3? 'range' si comporta diversamente in 2 e 3. – interjay

+2

Gli elenchi vengono passati per riferimento in python. Ciò significa che nel primo scenario, si aggiunge il puntatore a x, non il valore di x. Poiché x ora contiene un puntatore a x, si chiama in modo ricorsivo in quel punto. –

+0

@JacobH: dire "le liste sono passate per riferimento" fa sembrare che le liste possano comportarsi diversamente dagli altri oggetti. Tutti gli oggetti vengono passati allo stesso modo (anche se le persone discutono su quale sia la frase giusta per descriverlo). – DSM

risposta

9

In python2, s sono list s.

list s, e la maggior parte delle cose in Python sono oggetti con identità.

li = [0,1] 
li[1] = li # [0, [...]] 
       # ^----v 
id(li)  # 2146307756 
id(li[1])  # 2146307756 

Dal momento che si sta mettendo la lista all'interno , si sta creando una struttura dati ricorsiva .

+4

Si noti che questo è specifico per Python 2. Gli intervalli sono completamente diversi in Python 3, restituendo un oggetto 'range' ponderato, non un elenco, – MattDMo

+0

@Karoly, grazie per la risposta, ma non sono in grado di capire perché l'assegnazione del valore di 5. funzioni, qualsiasi cosa ho imparato è che se uso un [1 ] [0] = 5, quindi significa assegnare l'indice da 5 a 0 nell'elenco di elenchi dell'indice 1. – Rahul

+0

se si intende il mio esempio: 'li [1]' è 'li', quindi è semplicemente' li [0] = 5'. –

0

Prima questo è strano, e probabilmente non dovresti usarlo nella pratica. Il problema non è specifico della funzione range e ha a che fare con i riferimenti. Quando chiami x.append(x), in pratica dici che è x[-1] is x. Così, quando si modifica x[0], è anche modificare x[-1][0], x[-1][-1][0] ecc

per vedere che questo non è intervallo specifico, è possibile utilizzare copy.copy:

from copy import copy 

x = range(1) 
x.append(x) # here x[1] is reference to x itself (same object) 
print(x[0], x[1][0], x[1][1][0]) 
x[0] = 1 
print(x[0], x[1][0], x[1][1][0]) # all values change 

# 

x = range(1) 
x.append(copy(x)) # x[1] is a copy of x at previous state (new object) 
print(x[0], x[1][0]) # cannot call x[1][1][0] -> x[1][1] is an int 
x[0] = 1 
print(x[0], x[1][0]) # only the first value changes 

uscita:

(0, 0, 0) 
(1, 1, 1) 
(0, 0) 
(1, 0) 
Problemi correlati