List 사본에 문제가 있습니다.
그래서 E0
로부터 전화를 받으면을 호출 'get_edge'
하여 사본을 만듭니다 . 여기 추측 의 딥 카피 , 나는 통과 로 . 그러나 주요 기능에서. for 루프 이전
의 결과가 for 루프 이후 의 결과와 다른 이유는 무엇 입니까?E0
'E0_copy = list(E0)'
E0_copy
E0
E0_copy
'karger(E)'
'print E0[1:10]'
아래는 내 코드입니다.
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
답변
E0_copy
깊은 사본이 아닙니다. list()
(모두 list(...)
및 testList[:]
얕음)을 사용하여 딥 카피를 만들지 않습니다 .
당신은 사용 copy.deepcopy(...)
깊은 목록을 복사하는.
deepcopy(x, memo=None, _nil=[])
Deep copy operation on arbitrary Python objects.
다음 스 니펫을 참조하십시오-
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 10
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b # b changes too -> Not a deepcopy.
[[1, 10, 3], [4, 5, 6]]
이제 deepcopy
작업을 참조하십시오
>>> import copy
>>> b = copy.deepcopy(a)
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b
[[1, 10, 3], [4, 5, 6]]
>>> a[0][1] = 9
>>> a
[[1, 9, 3], [4, 5, 6]]
>>> b # b doesn't change -> Deep Copy
[[1, 10, 3], [4, 5, 6]]
답변
많은 프로그래머들이 하나 또는 두 개의 인터뷰 문제를 겪어 링크 목록을 딥 카피해야한다고 생각하지만이 문제는 생각보다 어렵습니다!
파이썬에는 두 가지 유용한 기능을 가진 “복사”라는 모듈이 있습니다
import copy
copy.copy()
copy.deepcopy()
주어진 인수가 복합 데이터 구조 (예 : list ) 인 경우 copy ()는 얕은 복사 함수입니다. 파이썬은 동일한 유형 (이 경우 새 목록 )의 다른 객체를 만들지 만 이전 목록의 모든 것에 대해 참조 만 복사됩니다
# think of it like
newList = [elem for elem in oldlist]
직관적으로, 우리는 deepcopy ()가 동일한 패러다임을 따를 것이라고 가정 할 수 있으며, 유일한 차이점은 각 요소 마다 재귀 적으로 deepcopy를 호출 한다는 것입니다 (mbcoder의 답변과 동일).
그러나 이것은 잘못입니다!
deepcopy ()는 실제로 원래 복합 데이터의 그래픽 구조를 유지합니다.
a = [1,2]
b = [a,a] # there's only 1 object a
c = deepcopy(b)
# check the result
c[0] is a # return False, a new object a' is created
c[0] is c[1] # return True, c is [a',a'] not [a',a'']
이것은 딥 카피 () 프로세스 중에 해시 테이블 (python의 사전)을 사용하여 “old_object ref를 new_object ref에 매핑”하는 데 사용됩니다. 이는 불필요한 중복을 방지하여 복사 된 복합 데이터의 구조를 보존합니다.
답변
목록의 내용이 기본 데이터 유형 인 경우 이해를 사용할 수 있습니다
new_list = [i for i in old_list]
다음과 같이 다차원 목록에 중첩시킬 수 있습니다.
new_grid = [[i for i in row] for row in grid]
답변
귀하의 경우 list elements
입니다 immutable objects
당신은 그렇지 않으면 사용해야합니다, 이것을 사용할 수 있습니다 deepcopy
에서 copy
모듈.
list
이와 같이 딥 카피에는 가장 짧은 방법을 사용할 수도 있습니다 .
a = [0,1,2,3,4,5,6,7,8,9,10]
b = a[:] #deep copying the list a and assigning it to b
print id(a)
20983280
print id(b)
12967208
a[2] = 20
print a
[0, 1, 20, 3, 4, 5, 6, 7, 8, 9,10]
print b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10]
답변
재귀 딥 카피 기능.
def deepcopy(A):
rt = []
for elem in A:
if isinstance(elem,list):
rt.append(deepcopy(elem))
else:
rt.append(elem)
return rt
편집 : Cfreak이 언급했듯이 이것은 이미 copy
모듈 에서 구현되었습니다 .
답변
목록을 트리로 사용하면 Python의 deep_copy는 다음과 같이 가장 간결하게 작성할 수 있습니다.
def deep_copy(x):
if not isinstance(x, list): return x
else: return map(deep_copy, x)
답변
다음은 목록을 딥 카피하는 방법의 예입니다.
b = [x[:] for x in a]
