Tengo algún problema con una copia de la lista:
Así Después de llegar E0
a 'get_edge'
, hago una copia de E0
llamando 'E0_copy = list(E0)'
. Aquí supongo que E0_copy
hay una copia profunda de E0
, y paso E0_copy
a 'karger(E)'
. Pero en la función principal.
¿Por qué el resultado de 'print E0[1:10]'
antes del ciclo for no es el mismo que después del ciclo for?
Debajo está mi código:
def get_graph():
f=open('kargerMinCut.txt')
G={}
for line in f:
ints = [int(x) for x in line.split()]
G[ints[0]]=ints[1:len(ints)]
return G
def get_edge(G):
E=[]
for i in range(1,201):
for v in G[i]:
if v>i:
E.append([i,v])
print id(E)
return E
def karger(E):
import random
count=200
while 1:
if count == 2:
break
edge = random.randint(0,len(E)-1)
v0=E[edge][0]
v1=E[edge][1]
E.pop(edge)
if v0 != v1:
count -= 1
i=0
while 1:
if i == len(E):
break
if E[i][0] == v1:
E[i][0] = v0
if E[i][1] == v1:
E[i][1] = v0
if E[i][0] == E[i][1]:
E.pop(i)
i-=1
i+=1
mincut=len(E)
return mincut
if __name__=="__main__":
import copy
G = get_graph()
results=[]
E0 = get_edge(G)
print E0[1:10] ## this result is not equal to print2
for k in range(1,5):
E0_copy=list(E0) ## I guess here E0_coypy is a deep copy of E0
results.append(karger(E0_copy))
#print "the result is %d" %min(results)
print E0[1:10] ## this is print2
Respuestas:
E0_copy
No es una copia profunda. No realiza una copia profunda utilizandolist()
(Amboslist(...)
ytestList[:]
son copias superficiales).Se utiliza
copy.deepcopy(...)
para copiar en profundidad una lista.Ver el siguiente fragmento:
Ahora mira la
deepcopy
operaciónfuente
Creo que muchos programadores se han encontrado con uno o dos problemas de entrevista en los que se les pide que copien en profundidad una lista vinculada, sin embargo, ¡este problema es más difícil de lo que parece!
en python, hay un módulo llamado "copia" con dos funciones útiles
copy () es una función de copia superficial, si el argumento dado es una estructura de datos compuesta, por ejemplo, una lista , entonces python creará otro objeto del mismo tipo (en este caso, una nueva lista ) pero para todo lo que esté dentro de la lista anterior, solo se copia su referencia
Intuitivamente, podríamos suponer que deepcopy () seguiría el mismo paradigma, y la única diferencia es que para cada elemento llamaremos recursivamente deepcopy , (al igual que la respuesta de mbcoder)
pero esto esta mal!
deepcopy () en realidad preserva la estructura gráfica de los datos compuestos originales:
esta es la parte difícil, durante el proceso de deepcopy () se usa una tabla hash (diccionario en python) para asignar: "old_object ref en new_object ref", esto evita duplicados innecesarios y por lo tanto preserva la estructura de los datos compuestos copiados
documento oficial
fuente
Si el contenido de la lista son tipos de datos primitivos, puede usar una comprensión
Puede anidarlo para listas multidimensionales como:
fuente
Si
list elements
esimmutable objects
así, puede usar esto; de lo contrario, debe usarlodeepcopy
desde elcopy
módulo.También puede usar el camino más corto para una copia profunda
list
como esta.fuente
solo una función recursiva de copia profunda.
Editar: como mencionó Cfreak, esto ya está implementado en el
copy
módulo.fuente
deepcopy()
copy
En cuanto a la lista como un árbol, el deep_copy en python se puede escribir de forma más compacta como
fuente
Aquí hay un ejemplo de cómo copiar en profundidad una lista:
fuente
Esto es mas pitonico
NOTA: Esto no es seguro con una lista de objetos referenciados
fuente