Is there an easy way to make a generator/iterator method in C?

So in Python:

class G:
    def __init__(self):
        self.value = 0

    def gen_func(self, n):
        for i in range(n):
            self.value += 1
            yield i

Is there a similar way to easily implement a generator/iterator method in C API?

What would be the best approach for this?

Hi,

for this, I am sure you will have to use a static integer variable inside the iter function so that it has persistence between function calls. Test this small script in your C editor and and see if it suits your needs. Type a 1 to call the iter function, and any other integer to exit. The script behavior is similar to that of yield in Python.

#include <stdio.h>

int iterator_in_c(int stop_value){
    
    int iter_value = 0;
    static int counter = 0;

    if (counter <= stop_value)
    {
        iter_value = counter;
        counter += 1;
        return iter_value;
    }
    else{
        counter = 0;
        return -1;
    }
}

int main()
{
    int number = 0;
    int result = 0;

    while(1){

        printf("\nDo you want to call the function (1 = yes, any other to exit)? ");
        scanf("%d", &number);
        
        if(number == 1){
            result = iterator_in_c(5);
            printf("The value of result is: %d", result);
        }
        else{
            printf("\nExiting the program. ");
            break;
        }
    } 
    
    return 0;
}

That does not scale to creating multiple interators.

I went ahead and generalized it a bit such that you can pass in any array as an argument. You can then obtain one of its values one at a time every time that the function is called. It is not as involved as the one in Python where you create a whole new variable and then iterate over it with the next() keyword, however. Note also that I am not raising an exception once ALL elements have been processed as Python does. I merely print a message that all the elements have been processed. If you’d like to raise an exception, modify it as you’d like.

Here it is included with a test code wrapper for testing convenience.

#include <stdio.h>

int iter_in_c(int *iter, int length){

    static int index = 0;

    if (index < length){

        return iter[index++];
    }
    else{
        
        return -1;
    }
}

int main()
{
    int number = 0;
    int result = 0;
    
    int values [] = {10, 20, 30, 40, 50};

    while(1){

        printf("\nDo you want to call the function (1 = yes, any other to exit)? ");
        scanf("%d", &number);
        
        if(number == 1){
            
            result = iter_in_c(values, sizeof(values) / sizeof(values[0]));
            
            if(result == -1)
            {
                printf("\n*** All values have been processed. ***\n");
            }
            else{
            printf("The value of result is: %d", result);
            }
        }
        else{
            printf("\nExiting the program. ");
            break;
        }
    } 
    
    return 0;
}

Much thanks for help.

I might have not been clear enough.

I am referring to C API of Python.

It isn’t hugely easy. Essentially gen_func has to return an extension type with a tp_iternext slot that gets the next value to be yielded.

You store the persistent state (i and a pointer to self in your case) on the extension type. When the iteration is done you return NULL from the function.

If you want it to look “perfectly” like a Python generator then you need more detail, but for the simple case that’s what you have to do.

I know how to do it the way it is usually done.

I am just making sure there isn’t an easier way.

e.g. In python:

class G1:
    def get_iter(self):
        yield 0

class G2:
    def get_iter(self):
        return Iter()

class Iter:
    end = False
    def __iter__(self):
        return self
    def __next__(self):
        if self.end:
            raise StopIteration
        self.end = True
        return 0

So in C, the approach is similar to G2. I was just wandering if there are any ways/tricks to follow something more similar to G1. I dont have much hope for it, but just double checking to make sure I am not missing something.