2012-08-28 4 views
1

순열 목적으로 생성자를 만들려고합니다. 파이썬에서 다른 방법을 사용하고 있습니다.하지만 다른 용도로 사용됩니다. 하지만 나는 값을 산출 할 수 없습니다. 도와 주실 수 있습니까?python에서 재귀 함수를 사용하여 yield

def perm(s,p=0,ii=0): 
    l=len(s) 
    s=list(s) 
    if(l==1):  
     print ''.join(s) 
    elif((l-p)==2): 
     yield ''.join(s) 
     yield ''.join([''.join(s[:-2]),s[-1],s[-2]]) 
     #print ''.join(s) 
     #print ''.join([''.join(s[:-2]),s[-1],s[-2]]) 
    else: 
     for i in range(p,l): 
      tmp=s[p] 
      s[p]=s[i] 
      s[i]=tmp   
      perm(s,p+1,ii) 
+0

'. '.join ([' '. join (s [: - 2]) 대신 s [ -1], s [-2]])''.join (s [: -2] + [s [-1], s [-2]])'또는 다소 덜 분명한' .join (s [: - 2] + s [: - 3 : -1])'(끝에서부터 세 번째 문자를 포함하여 끝까지 뒤쪽으로 슬라이스). – Dougal

답변

5

귀하의 라인 perm(s,p+1,ii) 정말 아무것도하지 않습니다 당신은하지만, 그 전화에서 얻을 수있는 경우는 다음 즉, 단지

>>> perm("fred") 
<generator object perm at 0xb72b9cd4> 

를 입력처럼

 for subperm in perm(s, p+1, ii): 
      yield subperm 

의 당신은 좋겠 얻을 수

>>> list(perm("abc")) 
['abc', 'acb', 'bac', 'bca', 'cab', 'cba'] 
>>> list(perm("abcd")) 
['abcd', 'abdc', 'acbd', 'acdb', 'adbc', 'adcb', 'bacd', 'badc', 'bcad', 'bcda', 'bdac', 'bdca', 'cabd', 'cadb', 'cbad', 'cbda', 'cdab', 'cdba', 'dabc', 'dacb', 'dbac', 'dbca', 'dcab', 'dcba'] 

>>> len(_) 
24 
>>> len(set(perm("abcd"))) 
24 

괜찮아 보이는군요. 나는 그 코드를 테스트하지 않았다.

현재 s[i]s[p]s[i], s[p] = s[p], s[i]으로 바꿀 수 있습니다. tmp 변수가 필요 없습니다.

추신 : 지금은 한 문자의 경우를 처리하지 않습니다.

+3

OP는'print' 문으로 판단 할 때 Python 2를 사용하지만 여전히 석판 후보 인 Python 3.3의'yield from perm (s, p + 1, ii)'도 이것을 수행합니다. :) – Dougal

+0

예, 꽤예요. : ^) – DSM

0

발전기에서 값을 반환하려면 언제든지 yield이어야합니다.

>>> def fact(n, result=1): 
    if n==0: return result 
    fact(n-1, result*n) 

그리고 당신이 아무것도 반환하지 않는 이유를 궁금해 :

>>> fact(5) 
>>> 

이유는, 함수가 재귀 적으로 호출 될 것입니다하지만이처럼 보였다 재귀 계승 기능을 한 것입니다 그 가치는 상실된다. 당신은하고 싶은 것 :

>>> def fact(n, result=1): 
    if n==0: return result 
    return fact(n-1, result*n) 

>>> fact(5) 
120 

유사하게, 알고리즘의 재귀 부분에 당신이 할 :

for i in range(p,l): 
     tmp=s[p] 
     s[p]=s[i] 
     s[i]=tmp   
     perm(s,p+1,ii) 

이되지 yield 아무것도하지만, 그래서 값 없음에서 perm(s,p+1,ii) 않습니다 전화가 반환됩니다 (편집 : 실제로, 그들 중 누구도 계산되지 않습니다). 재귀 호출의 결과를 반복하여 차례대로 반환하려고 할 것입니다.

for i in range(p,l): 
     tmp=s[p] 
     s[p]=s[i] 
     s[i]=tmp   
     for result in perm(s,p+1,ii): 
      yield result 
+0

사실상, perm (s, p + 1, ii)의 값 중 어느 것도 계산되지 않을 것이라는 점을 알 수 있습니다. – Dougal

+0

참으로 나는 초기 답변에서 그것을 가지고 있었지만 그것을 포함하지 않기로 결정했다 ... 편집 할 것이다. – Claudiu

관련 문제