J'ai un problème avec une copie de liste:
Donc, après mon E0
départ 'get_edge'
, je fais une copie E0
en appelant 'E0_copy = list(E0)'
. Ici, je suppose que E0_copy
c'est une copie profonde de E0
, et je passe E0_copy
dans 'karger(E)'
. Mais dans la fonction principale.
Pourquoi le résultat 'print E0[1:10]'
avant la boucle for n'est-il pas le même que celui après la boucle for?
Voici mon code:
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
Réponses:
E0_copy
n'est pas une copie complète. Vous ne faites pas de copie profonde en utilisantlist()
(Les deuxlist(...)
ettestList[:]
sont des copies superficielles).Vous utilisez
copy.deepcopy(...)
pour copier en profondeur une liste.Voir l'extrait suivant -
Maintenant voir l'
deepcopy
opérationla source
Je pense que beaucoup de programmeurs ont rencontré un ou deux problèmes d'entretien où ils sont invités à copier en profondeur une liste chaînée, mais ce problème est plus difficile qu'il n'y paraît!
en python, il existe un module appelé "copie" avec deux fonctions utiles
copy () est une fonction de copie superficielle, si l'argument donné est une structure de données composée, par exemple une liste , alors python créera un autre objet du même type (dans ce cas, une nouvelle liste ) mais pour tout ce qui se trouve dans l'ancienne liste, seule leur référence est copiée
Intuitivement, nous pourrions supposer que deepcopy () suivrait le même paradigme, et la seule différence est que pour chaque élément, nous appellerons récursivement deepcopy , (tout comme la réponse de mbcoder)
mais c'est faux!
deepcopy () conserve en fait la structure graphique des données composées d'origine:
c'est la partie la plus délicate, pendant le processus de deepcopy () une table de hachage (dictionnaire en python) est utilisée pour mapper: "old_object ref sur new_object ref", cela évite les doublons inutiles et préserve ainsi la structure des données composées copiées
doc officiel
la source
Si le contenu de la liste est des types de données primitifs, vous pouvez utiliser une compréhension
Vous pouvez l'imbriquer pour des listes multidimensionnelles comme:
la source
Si votre
list elements
sontimmutable objects
alors vous pouvez l' utiliser, sinon vous devez utiliserdeepcopy
ducopy
module.vous pouvez également utiliser le moyen le plus court pour une copie profonde
list
comme celui-ci.la source
juste une fonction de copie profonde récursive.
Edit: Comme Cfreak l'a mentionné, cela est déjà implémenté dans le
copy
module.la source
deepcopy()
fonction standard dans lecopy
moduleEn ce qui concerne la liste en tant qu'arbre, le deep_copy en python peut être écrit de la manière la plus compacte
la source
Voici un exemple de la façon de copier en profondeur une liste:
la source
C'est plus pythonique
REMARQUE: ce n'est pas sûr avec une liste d'objets référencés
la source