2012-05-31 2 views
0

과제에 대해 우리는 임의로 중첩 된 목록의 모든 요소를 ​​뒤집을 수있는 기능을 생성하도록 요청 받았다. 함수에 입력 이런 식으로 뭔가를 반환해야합니다 그래서 : 나는 해결책을 만들고 싶었역전 변이 입력

def arb_reverse(seq): 
    result = [] 
    for element in reversed(seq): 
     if not is_list(element): 
      result.append(element) 
     else: 
      result.append(arb_reverse(element)) 
    return result 

그러나 개인적인 도전의 조금 :

>>> seq = [1,[2,[3]]] 
>>> print arb_reverse(seq) 
[[[3],2],1] 
>>> seq = [9,[[],[0,1,[[],[2,[[],3]]]],[],[[[4],5]]]] 
>>> print arb_reverse(seq) 
[[[[5,[4]]],[],[[[[3,[]],2],[]],1,0],[]],9] 

나는 잘 작동 재귀 솔루션을 함께했다 재귀를 사용하지 않아도됩니다. 이 시도의 한 가지 버전은 내가 이해하지 못하는 이상한 행동을 초래했습니다. 명확히하기 위해, 나는이 버전이 제대로 작동하기를 기대하지는 않았지만, 결과적인 입력 변형은 의미가 없다. 여기에 문제의 반복 버전은 다음과 같습니다

def arb_reverse(seq): 
    elements = list(seq) #so input is not mutated, also tried seq[:] just to be thorough 
    result = [] 
    while elements: 
     item = elements.pop() 
     if isinstance(item, list): 
      item.reverse() #this operation seems to be the culprit 
      elements += item 
     else: 
      result.append(item) 
    return result 

이 평평 반 반전 목록 (어느 정도 예상)을 반환하지만 흥미로운 부분이 입력 (예상되지 않음)하는 일입니다 ...

>>> a = [1, [2, [3]]] 
>>> arb_reverse(a) 
[2, 3, 1] 
>>> a 
[1, [[3], 2]] 
>>> p = [1, [2, 3, [4, [5, 6]]]] 
>>> print arb_reverse(p) 
[2, 3, 4, 5, 6, 1] 
>>> print p 
[1, [[[6, 5], 4], 3, 2]] 

list() 또는 input[:]을 사용하여 입력에 포함 된 값을 elements과 같이 전달하면 입력이 변경되는 것을 방지 할 수 있다는 인상을받습니다. 그러나, 몇 가지 print 서술문은 후자의 방법이 원래의 목록을 돌연변이시키는 것에 손이 있음을 나중에 밝혀 냈습니다. 왜 그런가요?

답변

3

list() 호출은 원본에서 얕은 복사 목록을 사용하여 새 목록을 만듭니다.

이가 (here에서 도난) 시도 :

from copy import deepcopy 
listB = deepcopy(listA) 
+0

var = input [:]은 다음과 동일하다고 가정합니까? 따라서 새 목록이 만들어 지더라도 목록을 채우는 원래 값을 여전히 참조하고 있습니까? –

+1

정확합니다. –

+0

외부 모듈을 가져올 필요없이 원본 목록을 반복하고 모든 값이 어떻게 든 복사되는지 확인해야합니다. –

2

는 특히 l2[0].reverse()가 호출 될 때 발생하는 볼이 도구 http://people.csail.mit.edu/pgbovine/python/tutor.html

o1 = [1, 2, 3] 
o2 = [4, 5, 6] 

l1 = [o1, o2] 

l2 = list(l1) 

l2[0].reverse() 

print l2 
print l1 

을 통해 다음 코드를 실행 해보십시오.

list()을 호출하여 목록의 복사본을 만들 때 목록에서 동일한 개체를 계속 참조하는 것을 볼 수 있습니다.

+0

아직 그것을하지 않고, 나는 복사 된 목록 여전히 원본 목록을 채우는 개체를 참조한다고 가정합니다? –

+1

바로 목록의 단순한 복사본 일 뿐이며 목록에 포함 된 개체는 복제되지 않습니다. – Acorn

+0

진정한 복사본을 만들기 위해 별도의 함수가 필요하다는 점을 감안할 때 어느 길이의 입력에서 재귀는 솔루션과 관련하여 반복을 넘어서게 될까요? –