I've written a function to create combinations of inputs of an arbitrary length, so recursion seemed to be the obvious way to do it. While it's OK for a small toy example to return a list of the results, I'd like to yield them instead. I've read about yield from
, but don't fully understand how it is used, the examples don't appear to cover my use case, and hoping'n'poking it into my code has not yet produced anything that works. Note that writing this recursive code was at the limit of my python ability, hence the copious debug print statements.
This is the working list return code, with my hopeful non-working yield commented out.
def allposs(elements, output_length):
"""
return all zero insertion paddings of elements up to output_length maintaining order
elements - an iterable of length >= 1
output_length >= len(elements)
for instance allposs((3,1), 4) returns
[[3,1,0,0], [3,0,1,0], [3,0,0,1], [0,3,1,0], [0,3,0,1], [0,0,3,1]]
"""
output_list = []
def place_nth_element(nth, start_at, output_so_far):
# print('entering place_nth_element with nth =', nth,
# ', start_at =', start_at,
# ', output_so_far =', output_so_far)
last_pos = output_length - len(elements) + nth
# print('iterating over range',start_at, 'to', last_pos+1)
for pos in range(start_at, last_pos+1):
output = list(output_so_far)
# print('placing', elements[nth], 'at position', pos)
output[pos] = elements[nth]
if nth == len(elements)-1:
# print('appending output', output)
output_list.append(output)
# yield output
else:
# print('making recursive call')
place_nth_element(nth+1, pos+1, output)
place_nth_element(0, 0, [0]*output_length)
return output_list
if __name__=='__main__':
for q in allposs((3,1), 4):
print(q)
What is the syntax to use yield from
to get my list generated a combination at a time?