Edoardo Zucchelli
Edoardo Zucchelli

Reputation: 77

Dynamic Generator in Python

I need to create a service that can manage a dynamic resource (I'm thinking on a dynamic csv that is growing. In this case I used a list to make more easy to understand), returning the next item from an iterable.

If the list is finished, the output would be False and I need to wait that an element is added.

When the element if finally added, the generator should yield the new added item (this is the part that I can not understand how to do).

a_lst = [1, 2]


class DynamicGenerator:
    """
    Generic Generator that return item by item from a_lst and
    can append a new item when needed.
    """
    def __init__(self):
        global a_lst

    def gen_lst(self):
        for item in a_lst:
            yield item

    def grow_lst(self, new_item):
        a_lst.append(new_item)

class AvailableNextIterator:
    """
    Return next item from iterable if it's available,
    else return False.
    """
    def __init__(self, iterable):
        self.iterator = iterable

    def __next__(self):
        return next(self.iterator, False)


dg = DynamicGenerator()
gl = dg.gen_lst()

it = AvailableNextIterator(gl)

print(it.__next__())
print(it.__next__())
print(it.__next__())

dg.grow_lst(3)

print(it.__next__())

This is the code output:

1
2
False
False

This is the output that I need:

1
2
False
3

Upvotes: 1

Views: 888

Answers (1)

Prune
Prune

Reputation: 77837

Very simply, you exhausted the iteration before you added the last item; you already tripped the end-of-data exception for gen_list. You've dropped out of the loop, and there's no provision to re-enter. You can see this with a little simple tracing in that method:

def gen_lst(self):
    for item in a_lst:
        yield item
    print("gen_lst is out of data")
    yield "over the cliff's edge ..."

Now, the output is

1
2
gen_lst is out of data
over the cliff's edge ...
False

You seem to want a FIFO queue; I suggest that you use the available data structure in the readily-available packages, rather than trying to roll your own.

However, if this is a homework exercise:

  1. Mark your question as such, as required by SO posting standards;
  2. Research existing implementations.

Maintain the queue as an attribute of the instance, not an external variable. Your "generator" should check the queue directly, rather than depending on for to manage the iteration.

Upvotes: 1

Related Questions