최근에 저는 사소하지 않은 제약 조건으로 특정 시퀀스를 생성하는 함수를 작성했습니다. 문제는 자연스러운 재귀 솔루션과 함께 발생했습니다. 이제 상대적으로 작은 입력의 경우에도 시퀀스가 수천 개이므로 모든 시퀀스로 목록을 채우는 대신 알고리즘을 생성기로 사용하는 것을 선호합니다.
여기에 예가 있습니다. 재귀 함수를 사용하여 문자열의 모든 순열을 계산한다고 가정합니다. 다음 순진한 알고리즘은 추가 인수 '저장'을 취하고 찾을 때마다 순열을 추가합니다.
def getPermutations(string, storage, prefix=""):
if len(string) == 1:
storage.append(prefix + string) # <-----
else:
for i in range(len(string)):
getPermutations(string[:i]+string[i+1:], storage, prefix+string[i])
storage = []
getPermutations("abcd", storage)
for permutation in storage: print permutation
(비 효율성에 대해서는 신경 쓰지 마십시오. 이것은 단지 예시 일뿐입니다.)
이제 함수를 생성기로 바꾸고 싶습니다. 즉, 저장 목록에 추가하는 대신 순열을 생성합니다.
def getPermutations(string, prefix=""):
if len(string) == 1:
yield prefix + string # <-----
else:
for i in range(len(string)):
getPermutations(string[:i]+string[i+1:], prefix+string[i])
for permutation in getPermutations("abcd"):
print permutation
이 코드는 작동 하지 않습니다 (함수가 빈 생성기처럼 작동 함).
내가 뭔가를 놓치고 있습니까? 위의 재귀 알고리즘을 반복 알고리즘으로 바꾸지 않고 생성기로 바꾸는 방법이 있습니까?
yield from getPermutations(string[:i] + string[i+1:])
.이 방법은 여러면에서 더 효율적입니다!