Oleg
Oleg

Reputation: 132

How do change a parameter in a generator using a send method?

I want to change a parameter in my generator, but I don’t know how to do it correctly I think my generator is not working because it works inside while cycle, I want it to bring 0,1,2,3,4,0,1,2,3,4,5,6,7,8,9

def gen(k=None):
    z = 0
    exc = 0
    while True:
        yield z
        z += 1
        if z > 10:
            break
        if k is not None:
            z = k
            exc += 1
        if exc > 1:
            break


gen1 = gen()
for i in gen1:
    print(i)
    if i == 5:
        gen1.send(0)

Upvotes: 0

Views: 481

Answers (2)

Алексей Р
Алексей Р

Reputation: 7627

def gen():
    z, exc = 0, 0
    while True:
        k = yield z
        if k is not None:
            if exc:
                z -= 1
            else:
                z, k, exc = k - 2, None, exc + 1
        z += 1
        if z > 9 or exc > 1:
            break


gen1 = gen()
for i in gen1:
    print(i)
    if i == 4:
        gen1.send(0)
0
1
2
3
4
0
1
2
3
4
5
6
7
8
9

Upvotes: 1

defladamouse
defladamouse

Reputation: 625

I think you're misusing the send function. There's a good explanation of how it's used here: python generator "send" function purpose?

I couldn't find a way to acheive what you're looking for from a generator, but there's a slightly ugly using a small iterator class:

class gen2:

    def __init__(self, k=None):

        self.k = k
        self.z = -1
        self.exc = 0
        self.firstRet = False

    def __next__(self):

        if self.firstRet and (self.k is not None):
            self.z = self.k
            self.exc += 1

        if self.exc > 1:
            raise StopIteration

        self.z += 1
        if self.z > 10:
            raise StopIteration
        else:
            self.firstRet = True
            return self.z

    def __iter__(self):
        return self

    def reset_z(self, value):
        self.z = value-1


gen1 = gen2()
for i in gen1:
    print(i)
    if i == 5:
        gen1.reset_z(0)

I think this has the behavior you're looking for.

Upvotes: 1

Related Questions