2010-08-05 3 views
0

파이썬에서리스트의 모든 순열을 생성하는 순열 함수를 쓰고 있습니다.파이썬 순열 생성기 퍼즐

def permute(inputData, outputSoFar): 
    for elem in inputData: 
     if elem not in outputSoFar: 
      outputSoFar.append(elem) 
      if len(outputSoFar) == len(inputData): 
       print outputSoFar 
      else: 
       permute(inputData, outputSoFar) # --- Recursion 
      outputSoFar.pop() 

permute([1,2,3],[]) 

하지만이되지 않습니다 :

def permute(inputData, outputSoFar): 
    for elem in inputData: 
     if elem not in outputSoFar: 
      outputSoFar.append(elem) 
      if len(outputSoFar) == len(inputData): 
       yield outputSoFar 
      else: 
       permute(inputData, outputSoFar) # --- Recursion 
      outputSoFar.pop() 

for i in permute([1,2,3], []): 
    print i 

이 (목록의 사본을 얻을) 중 하나가 작동하지 않습니다 : 당신은

def permute(inputData, outputSoFar): 
    for elem in inputData: 
     if elem not in outputSoFar: 
      outputSoFar.append(elem) 
      if len(outputSoFar) == len(inputData): 
       yield outputSoFar[:] # --- Copy of the list 
      else: 
       permute(inputData, outputSoFar) # --- Recursion 
      outputSoFar.pop() 

for i in permute([1,2,3], []): 
    print i 

답변

3

또한 재귀 호출 (들)의 결과를 얻을해야합니다

def permute(inputData, outputSoFar): 
    for a in inputData: 
     if a not in outputSoFar: 
      if len(outputSoFar) == len(inputData) - 1: 
       yield outputSoFar + [a] 
      else: 
       for b in permute(inputData, outputSoFar + [a]): # --- Recursion 
        yield b 

for i in permute([1,2,3], []): 
    print i 

... 또는 (영업 코드에 가까운 일) :

def permute(inputData, outputSoFar): 
    for elem in inputData: 
     if elem not in outputSoFar: 
      outputSoFar.append(elem) 
      if len(outputSoFar) == len(inputData): 
       yield outputSoFar 
      else: 
       for permutation in permute(inputData, outputSoFar): 
        yield permutation # --- Recursion 
      outputSoFar.pop() 

for i in permute([1,2,3], []): 
    print i 
+0

이것은 작동하지만 재귀 호출에 yield를 추가해야하는 이유는 아직 모른다. –

+0

첫 번째 함수 호출 및 조건 (len (outputSoFar) == len (inputData) 인 경우)을 고려하십시오. 첫 번째 호출은 조건에 실패합니다 (입력에 요소가 하나만있는 경우가 아니면). 아무 것도 반환하지 않습니다. 대신 순열을 찾기 위해 재귀 호출에 의존해야하며 그렇게하면 순열을 얻을 것입니다. 그러나이 첫 번째 함수 호출로 반환 될 때 원래 호출자에게 반환해야합니다. (재귀 호출, 비 기본 호출은 비슷한 상황입니다.)이 기능이 없으면 재귀 트리의 잎만이 모든 것을 산출합니다. –

0

이 작품 왜 내 질문은 팝을 할 때 파괴적인 아이템 손실. 리스트를 변형시키지 말고 복사본을 사용하십시오.

대신 itertools.permutations 또는 itertools.combinations을 사용하십시오.

+0

-1 : 사실이 아니다. 추가 및 팝업이 정상적으로 작동합니다. 새로운 코드 itertools.permutations에 대해서는 –

+0

을 권장합니다. –

+0

itertools.permutation에 대해 알고 있습니다. 그러나,이 퍼즐의 목적은 파이썬 생성자/재귀에 대해 배우는 것입니다. –