Estou com algum problema com uma cópia da lista:
Então Depois que eu comecei E0
a partir 'get_edge'
, faço uma cópia E0
chamando 'E0_copy = list(E0)'
. Aqui eu acho que E0_copy
é uma cópia profunda E0
e eu passo E0_copy
adiante 'karger(E)'
. Mas na função principal.
Por que o resultado de 'print E0[1:10]'
antes do loop for não é o mesmo que após o loop for?
Abaixo está o meu 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
Respostas:
E0_copy
não é uma cópia profunda. Você não faz uma cópia profunda usandolist()
(Ambaslist(...)
etestList[:]
são cópias rasas).Você usa
copy.deepcopy(...)
para copiar profundamente uma lista.Veja o seguinte trecho -
Agora veja a
deepcopy
operaçãofonte
Acredito que muitos programadores se depararam com um ou dois problemas de entrevistas nos quais são solicitados a copiar em profundidade uma lista vinculada, mas esse problema é mais difícil do que parece!
em python, existe um módulo chamado "copy" com duas funções úteis
copy () é uma função superficial de cópia, se o argumento fornecido for uma estrutura de dados composta, por exemplo, uma lista , o python criará outro objeto do mesmo tipo (neste caso, uma nova lista ), mas para tudo dentro da lista antiga, somente sua referência é copiada
Intuitivamente, poderíamos assumir que deepcopy () seguiria o mesmo paradigma, e a única diferença é que, para cada elem, chamaremos recursivamente deepcopy (assim como a resposta do mbcoder)
mas isso está errado!
deepcopy () preserva a estrutura gráfica dos dados compostos originais:
esta é a parte complicada, durante o processo de deepcopy (), uma hashtable (dicionário em python) é usada para mapear: "old_object ref into new_object ref", isso evita duplicatas desnecessárias e preserva a estrutura dos dados compostos copiados
doc oficial
fonte
Se o conteúdo da lista for tipos de dados primitivos, você poderá usar uma compreensão
Você pode aninhar para listas multidimensionais como:
fonte
Se o seu
list elements
sãoimmutable objects
, em seguida, você pode usar este, caso contrário, você tem que usardeepcopy
a partircopy
do módulo.você também pode usar o caminho mais curto para cópias profundas,
list
como esta.fonte
apenas uma função de cópia profunda recursiva.
Edit: Como o Cfreak mencionou, isso já está implementado no
copy
módulo.fonte
deepcopy()
função nocopy
móduloEm relação à lista como uma árvore, o deep_copy em python pode ser escrito de forma mais compacta como
fonte
Aqui está um exemplo de como copiar uma lista em profundidade:
fonte
Isso é mais pitônico
NOTA: Isso não é seguro com uma lista de objetos referenciados
fonte