2011-09-26 3 views
1

문자열의 고유 순열 수를 계산하는 함수를 작성하려고합니다. 예를 들어 aaa1이고 abc6을 반환합니다.
이 같은 방법을 쓰고 있어요 :lambda 함수에서 reduce()를 사용하여 math.factorial 사용

(의사 코드 : A, B, C는 각각의 고유 한 문자의 발생 횟수가

len(string)!/(A!*B!*C!*...) 

. 예를 들어 'aaa' 문자열은 3!/3! = 1이고 'abc' 문자열은 3!/(1! * 1! * 1!) = 6입니다.

내 코드는 지금까지처럼 :

def permutations(n): 
    ''' 
    returns the number of UNIQUE permutations of n 
    ''' 
    from math import factorial 

    lst = [] 
    n = str(n) 
    for l in set(n): 
     lst.append(n.count(l)) 

    return factorial(len(n))/reduce(lambda x,y: factorial(x) * factorial(y), lst) 

모든 나는 단지 하나의 고유 한 문자가 문자열을 전달하려고 할 때를 제외하고 잘 작동, 즉 aaa - 내가 잘못된 답변을 얻을 :

>>> perm('abc') 
6 
>>> perm('aaa') 
2 
>>> perm('aaaa') 
6 

이제 문제는 길이 1의 목록에서 계승으로 람다 함수를 실행하는 것입니다. 이유는 모르겠지만.

>>> reduce(lambda x,y: x * y, [3]) 
3 
>>> reduce(lambda x,y: x + y, [3]) 
3 

이 하나가되지 않습니다 : 내가 다른 일을해야 뭔가

>>> reduce(lambda x,y: ord(x) + ord(y), ['a']) 
'a' 
>>> reduce(lambda x,y: ord(x) + ord(y), ['a','b']) 
195 

거기에 그 두 가지 요소를 기대하는 경우에도 대부분의 다른 람다 함수는 길이 1의 목록에서 작동? 나는 이것을 피할 수있는 다양한 방법으로 함수를 다시 작성할 수 있다는 것을 알고있다. (예를 들어, lambda을 사용하지 않는다.) 그러나 이것이 특별히 작동하지 않는 이유를 찾고있다.

답변

1

파이썬의 reduce 함수는 기본 (초기) 값을 항상 알 필요는 없습니다. 초기 값을 갖는 버전이 있어야합니다. 합리적인 초기 값을 제공하면 reduce이 아름답게 작동합니다.

또한, 코멘트에서, 당신은 아마 당신의 람다의 두 번째 인수에 factorial을 사용해야합니다

reduce(lambda x,y: x * factorial(y), lst, 1) 
+0

@agf 및 플래티넘 : 목록에 하나의 요소 목록의 동작은 당신이 ord() 0으로 문자로 initializer를 설정할 수 있습니다 당신의 ord() 람다, 예를 들어, 일치되도록 음 Azure - 고마워,이 크기가 1 목록에 대해 작동하지만 큰 아무것도 실패합니다. 왜? 문서는 초기 값이리스트가 단순히 하나의 요소 일 때처럼 처리되어야한다고 말한다. – HodofHod

+4

'reduce (lambda x, y : x * factorial (y), lst, 1)'을 시도해 볼 수도 있습니다. 당신이 계산 한 람다는'((1! * 2!)! * 3!)! ... '. – cHao

+1

첫 번째 인수에'factorial (x)'를 사용해야합니까? 모든 팩토리얼의 제품을 원한다면'reduce (lambda x, y : x * factorial (y), lst, 1)'을 사용해야합니다. –

0

는 순서의 처음 두 요소의 결과를 계산 처음으로 작품을 감소 다음 의사 - 재귀 적으로 거기에서 뒤 따른다. 크기 1의 목록은 특별한 경우입니다.

여기 지능형리스트를 사용합니다 :

prod([ factorial(val) for val in lst ]) 

행운을 빕니다!

1

len(s)!/A!*B!*C!을 사용하려는 경우 factorial(factorial(A)*factorial(B))*factorial(C)을 계산하므로 reduce()을 사용하면 작동하지 않습니다. 즉, 교환 작업이 필요합니다.

대신, 다음 둘을 곱하면, 계승의 목록을 생성해야합니다 :

import operator 
reduce(operator.mul, [factorial(x) for x in lst]) 
2

reduce() 설명서를 참조하십시오, 모든 다른 요소 앞에 위치 선택 '초기화'인수가

>>> reduce(lambda x, y: ord(x) + ord(y), ['a'], chr(0)) 
97 
관련 문제