2009-05-12 6 views
2

안녕하세요. 저는 반복적 인 생성기를 사용하여 숫자의 고정 정수 파티션을 만들었습니다. 범위 지정 문제로 인해 혼란 스러웠습니다.파이썬 재귀 생성기의 범위

코드는이 스 니펫과 유사합니다.

def testGen(a,n): 
    if n <= 1: 
     print('yield', a) 
     yield a 
    else: 
     for i in range(2): 
      a[i] += n 
      for j in testGen(a,n-i-1): 
       yield j 

혼란은 아래에 나와 있습니다.

>>> list(testGen([1,2],4)) 
yield [10, 2] 
yield [10, 4] 
yield [10, 7] 
yield [12, 11] 
yield [12, 13] 
[[12, 13], [12, 13], [12, 13], [12, 13], [12, 13]] 

단순히 (예를 들어, 재귀 호출에 a[:] 전달) 배열의 카피를 사용하여 정답을 얻을 수 있습니다하지만 난 여전히 위의 동작을 이해하지 않습니다. 인쇄 문과 산출 값이 다른 이유는 무엇입니까?

답변

2

print 문은 특정 시점의 목록을 표시합니다. 코드를 실행하면 목록이 변경되므로 마지막에 목록을 검토 할 때 그 값이 표시됩니다.

당신은 단계별로하여 관찰 할 수 있습니다 :

>>> g = testGen([1,2],4) 
>>> g.next() 
('yield', [10, 2]) # note brackets in print statement because I'm on python 2.5 
[10, 2] 
>>> g.next() 
('yield', [10, 4]) 
[10, 4] 
>>> g.next() 
('yield', [10, 7]) 
[10, 7] 
>>> g.next() 
('yield', [12, 11]) 
[12, 11] 
>>> g.next() 
('yield', [12, 13]) 
[12, 13] 
2

배열을 돌연변이시키고있는 것 같아요. 그래서 당신이 인쇄 할 때 특정 값을 가지면 다음 번에 실제로 값을 업데이트 한 것입니다. 결국 동일한 배열에 대한 참조가 5 개이므로 동일한 값을 5 번 사용합니다.

+0

'a [i] + = n'은 확실히 배열을 변형시킵니다. –

0

인쇄 및 수율 문이 다른 당신이 개 수율있는 동안 당신은 단지 하나의 인쇄 문이 있기 때문이다. 이것을 시도하십시오 :

def testGen(a,n): 
    if n <= 1: 
     print('yield', a) 
     yield a 
    else: 
     for i in range(2): 
      a[i] += n 
      for j in testGen(a,n-i-1): 
       print('yield', j) 
       yield j 

>>> list(testGen([1,2],4)) 
('yield', [10, 2]) 
('yield', [10, 2]) 
('yield', [10, 2]) 
('yield', [10, 2]) 
('yield', [10, 4]) 
('yield', [10, 4]) 
('yield', [10, 4]) 
('yield', [10, 4]) 
('yield', [10, 7]) 
('yield', [10, 7]) 
('yield', [10, 7]) 
('yield', [12, 11]) 
('yield', [12, 11]) 
('yield', [12, 11]) 
('yield', [12, 13]) 
('yield', [12, 13]) 
('yield', [12, 13]) 
[[12, 13], [12, 13], [12, 13], [12, 13], [12, 13]] 

복사본을 만드는 대신 동일한 목록을 지나가므로 마지막 결과가 답입니다.

2

목록은 변경 가능한 개체입니다. 목록을 전달하면 생성기가 해당 목록에서 적절한 작업을 수행 한 다음 목록에 대한 모든 참조가 같은 목록을 가리 킵니다.