Python: how to make a recursive generator function

2024/10/12 13:22:05

I have been working on generating all possible submodels for a biological problem. I have a working recursion for generating a big list of all the submodels I want. However, the lists get unmanageably large pretty fast (N=12 is just possible in the example below, N>12 uses too much memory). So I wanted to convert it to a generator function using yield instead, but I'm stuck.

My working recursive function looks like this:

def submodel_list(result, pat, current, maxn):''' result is a list to append topat is the current pattern (starts as empty list)current is the current number of the patternmaxn is the number of items in the pattern'''if pat:curmax = max(pat)else: curmax = 0for i in range(current):if i-1 <= curmax:newpat = pat[:]newpat.append(i)if current == maxn:result.append(newpat)else:submodel_generator(result, newpat, current+1, maxn)result = []
submodel_list(result, [], 1, 5)

That gives me the expected list of submodels for my purposes.

Now, I want to get that same list using a recursion. Naively, I thought I could just switch out my result.append() for a yield function, and the rest would work OK. So I tried this:

def submodel_generator(pat, current, maxn):'''same as submodel_list but yields instead'''if pat:curmax = max(pat)else: curmax = 0for i in range(current):print i, current, maxnif i-1 <= curmax:print curmaxnewpat = pat[:]newpat.append(i)if current == maxn:yield newpatelse:submodel_generator(newpat, current+1, maxn)b = submodel_generator([], 1, 5)
for model in b: print model

But now I get nothing. A (very dumb) bit of digging tells me the function gets to the final else statement once, then stops - i.e. the recursion no longer works.

Is there a way to turn my first, clunky, list-making function into a nice neat generator function? Is there something silly I've missed here? All help hugely appreciated!

Answer

You should change this:

submodel_generator(newpat, current+1, maxn)

to this:

for b in submodel_generator(newpat, current+1, maxn):yield b

This will recursively yield the value from successive calls to the function.

[Update]: Note that as of Python 3.3, you can use the new yield from syntax:

yield from submodel_generator(newpat, current+1, maxn)
https://en.xdnf.cn/q/69649.html

Related Q&A

Change default options in pandas

Im wondering if theres any way to change the default display options for pandas. Id like to change the display formatting as well as the display width each time I run python, eg:pandas.options.display.…

python-messaging Failed to handle HTTP request

I am using the code below to try to send an MMS message with python-messaging https://github.com/pmarti/python-messaging/blob/master/doc/tutorial/mms.rst Although the connection seems to go smoothly I …

Plotting confidence and prediction intervals with repeated entries

I have a correlation plot for two variables, the predictor variable (temperature) on the x-axis, and the response variable (density) on the y-axis. My best fit least squares regression line is a 2nd or…

Saving and Loading of dataframe to csv results in Unnamed columns

prob in the title. exaple:x=[(a,a,c) for i in range(5)] df = DataFrame(x,columns=[col1,col2,col3]) df.to_csv(test.csv) df1 = read_csv(test.csv)Unnamed: 0 col1 col2 col3 0 0 a a c 1 …

Python: print specific character from string

How do I print a specific character from a string in Python? I am still learning and now trying to make a hangman like program. The idea is that the user enters one character, and if it is in the word…

Python AttributeError: module string has no attribute maketrans

I am receiving the below error when trying to run a command in Python 3.5.2 shell:Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32 Type "copyrig…

How to add attribute to class in python

I have: class A:a=1b=2I want to make as setattr(A,c)then all objects that I create it from class A has c attribute. i did not want to use inheritance

Number of occurrence of pair of value in dataframe

I have dataframe with following columns:Name, Surname, dateOfBirth, city, countryI am interested to find what is most common combination of name and surname and how much it occurs as well. Would be nic…

how do i dump a single sqlite3 table in python?

I would like to dump only one table but by the looks of it, there is no parameter for this. I found this example of the dump but it is for all the tables in the DB: # Convert file existing_db.db to SQL…

Django automatically create primary keys for existing database tables

I have an existing database that Im trying to access with Django. I used python manage.py inspectdb to create the models for the database. Currently Im able to import the models into the python shell h…