हाल ही में मैंने nontrivial बाधाओं के साथ कुछ दृश्यों को उत्पन्न करने के लिए एक फ़ंक्शन लिखा। समस्या एक प्राकृतिक पुनरावर्ती समाधान के साथ आई थी। अब ऐसा होता है कि, अपेक्षाकृत छोटे इनपुट के लिए भी, अनुक्रम कई हजारों होते हैं, इस प्रकार मैं अपने एल्गोरिथ्म को एक जनरेटर के रूप में उपयोग करना पसंद करूंगा बजाय सभी अनुक्रमों के साथ एक सूची को भरने के लिए।
यहाँ एक उदाहरण है। मान लीजिए कि हम एक पुनरावर्ती फ़ंक्शन के साथ एक स्ट्रिंग के सभी क्रमपरिवर्तन की गणना करना चाहते हैं। निम्नलिखित भोली एल्गोरिथ्म एक अतिरिक्त तर्क 'भंडारण' लेता है और जब भी यह एक पाता है, तो इसके लिए एक क्रमपरिवर्तन करता है:
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:])
, जो कई मायनों में अधिक कुशल है!