Mam problem z kopią listy:
Więc po powrocie E0
z 'get_edge'
, robię kopię E0
, dzwoniąc 'E0_copy = list(E0)'
. Myślę, że E0_copy
jest to głęboka kopia E0
i przechodzę E0_copy
do 'karger(E)'
. Ale w głównej funkcji.
Dlaczego wynik 'print E0[1:10]'
przed pętlą for nie jest taki sam jak wynik po pętli for?
Poniżej mój kod:
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
Odpowiedzi:
E0_copy
nie jest głęboką kopią. Nie tworzysz głębokiej kopii za pomocąlist()
(Bothlist(...)
itestList[:]
są płytkie kopie).Używasz
copy.deepcopy(...)
do głębokiego kopiowania listy.Zobacz następujący fragment -
Teraz zobacz
deepcopy
operacjęźródło
Uważam, że wielu programistów napotkało jeden lub dwa problemy z rozmową kwalifikacyjną, podczas których proszono ich o dokładne skopiowanie połączonej listy, jednak ten problem jest trudniejszy niż się wydaje!
w Pythonie jest moduł o nazwie "kopia" z dwiema przydatnymi funkcjami
copy () jest funkcją płytkiego kopiowania, jeśli podany argument jest złożoną strukturą danych, na przykład listą , to python utworzy kolejny obiekt tego samego typu (w tym przypadku nową listę ), ale dla wszystkiego ze starej listy, kopiowane jest tylko ich odniesienie
Intuicyjnie moglibyśmy założyć, że deepcopy () będzie postępować zgodnie z tym samym paradygmatem, a jedyną różnicą jest to, że dla każdego elementu będziemy rekurencyjnie nazywać deepcopy (tak jak odpowiedź mbcoder)
ale to jest złe!
deepcopy () faktycznie zachowuje strukturę graficzną oryginalnych danych złożonych:
to jest trudna część, podczas procesu deepcopy () hashtable (słownik w Pythonie) jest używany do mapowania: "ref old_object ref na new_object ref", co zapobiega niepotrzebnym duplikatom, a tym samym zachowuje strukturę kopiowanych danych złożonych
oficjalny doc
źródło
Jeśli zawartość listy to prymitywne typy danych, możesz użyć zrozumienia
Możesz go zagnieżdżać dla list wielowymiarowych, takich jak:
źródło
Jeśli
list elements
sąimmutable objects
następnie można użyć tego, w przeciwnym razie trzeba korzystaćdeepcopy
zcopy
modułu.możesz również użyć najkrótszej drogi do głębokiego kopiowania, takiego
list
jak ten.źródło
po prostu rekurencyjna funkcja głębokiego kopiowania.
Edycja: Jak wspomniał Cfreak, jest to już zaimplementowane w
copy
module.źródło
deepcopy()
copy
Jeśli chodzi o listę jako drzewo, deep_copy w Pythonie można najbardziej zwięźle zapisać jako
źródło
Oto przykład, jak głęboko skopiować listę:
źródło
To jest bardziej pytoniczne
UWAGA: Nie jest to bezpieczne w przypadku listy obiektów, do których istnieją odniesienia
źródło