2012-01-14 8 views
4

의 종류가 추적 할 수없는 가망 만 깊은 같은파이썬은 ..

예리스트하는 딕셔너리 또는 튜플과 같은 객체의 특정 유형, 복사하는 것입니다 deepcopy : [[1, <SomeObj>], <OtherObj>]

나는 깊은 복사 할을 첫 번째 목록 (그리고 물론 .. 1). 그러나 SomeObj 또는 OtherObj이 아닙니다. 그들은 refereces로 체재해야한다.

내가 익숙하지 않은거야 아니면 내가 내 자신의 기능을? 작성해야 할 몇 가지 기능 ...

답변

3

내가 아는 한, 그렇게 할 수있는 유틸리티가 없습니다. 내장 된 copydeepcopy은 개체가 자신의 __copy____deepcopy__ 메서드를 제공하여 기본 동작을 재정의 할 것을 요구합니다. 어떤 좋은 생각이 아니므로 항상 같은 종류의 사본을 원한다면 ...

그렇게하기위한 기능을 작성하는 것은 어렵지 않아야합니다. 여기리스트, 튜플 및 dicts 작동 예는 다음과 같습니다

def mycopy(obj): 
    if isinstance(obj, list): 
     return [mycopy(i) for i in obj] 
    if isinstance(obj, tuple): 
     return tuple(mycopy(i) for i in obj) 
    if isinstance(obj, dict): 
     return dict(mycopy(i) for i in obj.iteritems()) 
    return obj 
+2

는이보다 효율적으로 할 것 튜플 지점과의'[''및]'은' ['와']'를 사용하고'.items()'를 dict 브랜치에서'.iteritems()'로 바꾼다. 이러한 변경은 Pythonic 스타일입니다. –

+0

@ChrisMorgan 답변이 업데이트되었습니다. 팁 주셔서 감사합니다, 나는이 형태를 몰랐다. – mgibsonbr

+2

만약 당신이 익숙하지 않다면, (a) 생성자 표현식 ('['과']'을 꺼낼 때 얻는 것, 그렇지 않으면리스트 이해력)과 (b) 반복자 dict.items()'는리스트를 생성하고,'dict.iteritems()'는 반복자를 생성하며, 자세한 것은'dict' 문서를 참조하십시오. –

1

와 나는 단지 deepcopy됩니다 어떤 파이썬 도구의 인식 아니에요 그렇게 할 수인가요 기본 유형 및 기타 요소를 참조로 유지합니다.

나는 (20 라인 이하) 작은 재귀 함수를 작성할 수 있어야한다고 생각한다.

4

당신은 당신이 그것을 필요로하는 각 클래스에서 __deepcopy__ 방법을 재정 의하여 아주 쉽게 copy.deepcopy와 함께 할 수있는 서로 다른 복사 동작에 따라합니다. 상황은, 당신은 단지 그것을 다시 다음 런타임에 __deepcopy__ 기능을 설정할 수 있습니다 : 제거하여 더 큰 것들에 대한

import copy 
class OtherObject(object): 
    pass 

l = [[1, 2, 3], [4, 5, 6], OtherObject()] 
# first, save the old deepcopy if there is one 
old_deepcopy = None 
if hasattr(OtherObject, __deepcopy__): 
    old_deepcopy = OtherObject.__deepcopy__ 

# do a shallow copy instead of deepcopy 
OtherObject.__deepcopy__ = lambda self, memo: self 
l2 = copy.deepcopy(l) 
# and now you can replace the original behavior 
if old_deepcopy is not None: 
    OtherObject.__deepcopy__ = old_deepcopy 
else: 
    del OtherObject.__deepcopy__ 

>>> l[0] is l2[0] 
False 
>>> l[1] is l2[1] 
False 
>>> l[2] is l2[2] 
True