2012-03-15 8 views
5

Estoy confundido con la referencia de Python. Consideremos el siguiente ejemplo:¿Cómo funciona la referencia de Python?

Mi tarea: Para editar cada elemento en la lista

d = { 'm': [1,2,3] } 
m = d['m'] 
m = m[1:] # m changes its reference to the new sliced list, edits m but not d (I wanted to change d) 

mismo modo:

d = { 'm': [1,2,3] } 
m = d['m'] 
m = m[0] # As per python referencing, m should be pointing to d['m'] and should have edited d 

en Python todo va por referencia, a continuación, cuando es un objeto nuevo ¿creado? ¿Necesitamos siempre copy y deepcopy del módulo copy para hacer copias de objetos?

Por favor, aclare.

+1

Si usted es un estudiante visual, [esto es] (http://people.csail.mit.edu/pgbovine/python /) un buen tutorial – forivall

+0

Comentario extremadamente útil Sr. @jordoex - ¡Seriamente increíble! –

Respuesta

11

En Python una variable no es una caja que contiene las cosas, es un nombre que apunta a un objeto. En su código:

  • d = { 'm': [1,2,3] } -> une el nombre d a un diccionario
  • m = d['m'] -> une el nombre m a una lista
  • m = m[1:] -> une el nombre m a otra lista

Su tercera línea no está cambiando m en sí, pero a lo que apunta m.

Para editar los elementos de la lista de lo que puede hacer es:

m = d['m'] 
for i, item in enumerate(m): 
    result = do_something_with(item) 
    m[i] = result 
+0

¿Hay alguna otra manera de editar cada elemento de esta lista aparte de 'enumerar'? –

+0

"Un nombre que apunta a un objeto" podría ser confuso, ya que "puntero" no es terminología de Python. Solo diría "es un nombre para un objeto". –

+0

"Su tercera línea no está cambiando m sí, pero lo que m está apuntando a" podría ser un poco confuso para el lector. Para ser más explícito: "la tercera línea cambia m de apuntar a una cosa (d ['m']) a apuntar a otra cosa ([2,3])". –

5

Ethan Furman hizo un excelente trabajo de explicar cómo Python internos de trabajo, no voy a repetirlo.

Desde m realmente representa la lista dentro del diccionario, puede modificarlo. Simplemente no puede reasignarlo a algo nuevo, que es lo que sucede cuando usa = para equipararlo a un nuevo segmento.

para rebanar el primer elemento de la lista, por ejemplo:

>>> m[0:1] = [] 
>>> d 
{'m': [2, 3]} 
+4

Odio los votos negativos, si hago algo mal, me gusta averiguar por qué. Esta respuesta ha sido probado en Python 2.7 utilizando un lenguaje recomendado: http://docs.python.org/library/stdtypes.html#mutable-sequence-types –

+0

Creo que es una buena perspectiva de la marca, y yo no sé por qué se downvoted ... –

+2

para eliminar elementos o rodajas de una lista por lo general prefieren el más explícito del 'm [0] '. Por supuesto, esta es una preferencia estilística, y no tengo idea de por qué alguien votó negativamente. Mi suposición es que muchos de esos votos negativos aparentemente aleatorios resultan de pantallas demasiado pequeñas de teléfonos inteligentes. –

4

en Python todo va por referencia

En Python, todo es una referencia, y las referencias pasar por valor

Si desea utilizar esos términos. Pero esos términos hacen que las cosas sean más difíciles de entender.

mucho más sencillo: en Python, una variable es un nombre para un objeto. = se usa para cambiar a qué objeto se refiere un nombre. El lado izquierdo puede referirse a parte de un objeto existente, en cuyo caso el objeto completo se cambia reemplazando esa parte. Esto se debe a que el objeto, a su vez, no contiene realmente sus partes, sino que contiene más nombres, que pueden provocar que comiencen a referirse a cosas diferentes.

¿Cuándo se crea un objeto nuevo?

Los objetos se crean cuando se crean (utilizando el constructor de la clase, o en el caso de los tipos incorporados que tienen una representación literal, escribiendo un literal). No entiendo cómo esto es relevante para el resto de su pregunta.

m = m[1:] # m changes its reference to the new sliced list 

Sí, por supuesto. Ahora m se refiere al resultado de evaluar m[1:].

edits m but not d (I wanted to change d) 

Sí, por supuesto. ¿Por qué le cambia d? No era un tipo de magia, simplemente era el resultado de evaluar d['m']. Exactamente lo mismo sucede en ambas líneas. mirada

Vamos a un ejemplo más simple.

m = 1 
m = 2 

¿Esto 1 para convertirse en 2? No claro que no. Los enteros son inmutables. Pero ocurre lo mismo: m tiene como objetivo nombrar una cosa, y luego nombrar otra cosa.

O, de otra manera: si las "referencias" iban a funcionar como usted espera, entonces la línea m = m[1:] sería recursiva. Estás esperando que significa "en cualquier lugar que se ve m, lo tratan como si significara m[1:]". Bueno, en ese caso, habría m[1:] significa realmente m[1:][1:], lo que significaría entonces m[1:][1:][1:], etc.

Cuestiones relacionadas