Python: deepcopy (lista) vs new_list = old_list

Estoy haciendo el ejercicio 9 desde http://openbookproject.net/thinkcs/python/english2e/ch09.html y me he encontrado con algo que no tiene sentido.

El ejercicio sugiere usar copy.deepcopy() para facilitar mi tarea, pero no veo cómo podría.

 def add_row(matrix): """ >>> m = [[0, 0], [0, 0]] >>> add_row(m) [[0, 0], [0, 0], [0, 0]] >>> n = [[3, 2, 5], [1, 4, 7]] >>> add_row(n) [[3, 2, 5], [1, 4, 7], [0, 0, 0]] >>> n [[3, 2, 5], [1, 4, 7]] """ import copy # final = copy.deepcopy(matrix) # first way final = matrix[:] # second way li = [] for i in range(len(matrix[0])): li.append(0) # return final.append(li) # why doesn't this work? final.append(li) # but this does return final 

Estoy confundido de por qué el libro sugiere usar deepcopy() cuando una list[:] simple list[:] copia. ¿Lo estoy usando mal? ¿Mi función está completamente fuera de lugar?

También tengo algo de confusión devolviendo valores. La pregunta es documentos en el código anterior.

TIA

Hiciste dos preguntas:

Copia profunda vs. superficial

matrix[:] es una copia superficial ; solo copia los elementos almacenados directamente en ella, y no duplica de forma recursiva los elementos de matrices u otras referencias dentro de sí mismo. Eso significa:

 a = [[4]] b = a[:] a[0].append(5) print b[0] # Outputs [4, 5], as a[0] and b[0] point to the same array 

Lo mismo sucedería si almacenara un objeto en un archivo.

deepcopy() es, naturalmente, una copia profunda : hace copias de cada uno de sus elementos recursivamente, hasta el final del árbol:

 a = [[4]] c = copy.deepcopy(a) a[0].append(5) print c[0] # Outputs [4], as c[0] is a copy of the elements of a[0] into a new array 

Regresando

return final.append(li) es diferente de llamar append y devolver final porque list.append no devuelve el objeto de la lista en sí, devuelve None

Ver la documentación en copia profunda y superficial .

 list[:] 

No crea copias de elementos nesteds.

Para su problema con respecto a la statement de devolución, parece que no está dentro de una función cuando la llama, asumo que sucedió al pegar el código aquí. Respecto al valor de retorno Michael Mrozek tiene razón.