I'm trying to generate permutations of a list in order, but without enumerating all of the possible permutations. My algorithm is recursive, with a immutable "head" being passed to each sub-call, and the "tail" being permuted in order by the sub-call.
My understanding of "yield from" was that once the interior generator runs out of elements it's generating, the exterior generator continues on its code path. I'm getting confused though because the generator only generates the first permutation, and then raises a StopIteration
exception on the next call to next
.
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def permutations(head, tail):
if tail == []:
yield head
else:
for num in tail:
new_head = head + [num]
new_tail = tail
new_tail.remove(num)
yield from permutations(new_head, new_tail)
perm_generator = permutations([], nums)
for i in range(1000000):
res = next(perm_generator)
print(res)
Output is:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Traceback (most recent call last):
File "024.py", line 19, in <module>
res = next(perm_generator)
StopIteration
I know itertools
makes this easy, but I'd like to do this with custom generators.
The most similar previous questions I've found are here and I guess here. What am I misunderstanding/doing wrong?