-3

I am learning generator in python,here the functions:

import math
def is_primes(number):
    if number > 1:
        if number == 2:
            return True
        if number % 2 == 0:
            return False
        for current in range(3, int(math.sqrt(number) + 1), 2):
            if number % current == 0:
                return False
        return True
    return False


def get_primes1(number):
    while True:
        if is_primes(number):
            yield number
        number +=1

def get_primes2(number):
    while True:
        if is_primes(number):
            number=yield number
        number +=1

when using the send function:

a=get_primes1(2)
b=get_primes2(2)
a.send(None)#return 2
b.send(None)#return 2
a.send(1)#return 3,the parameter in send() looks useless.
b.send(1)#return 1,normal

when using the "a.send(1)" and "b.send(1)" repeatly,a.send(1) return the bigger value but b.send(1) still return the same value.why there is difference?

i check the meaning of send function:

Resumes the execution and ``sends'' a value into the generator function. The value argument becomes the result of the current yieldexpression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receieve the value.

David Lee
  • 11
  • 5
  • 2
    Doesn't your example demonstrate exactly what you're asking? The thing that's different *is the thing that's different!* `.send` only has an effect if you assign the result of the `yield`, as you do in `get_primes2`. If you `.send(None)`, it's ignored either way. – jonrsharpe Apr 24 '16 at 12:03
  • i think "send(x)" and x will be sent to the get_primes1() and yield again...@jonrsharpe – David Lee Apr 24 '16 at 12:14
  • 2
    It's not clear what your question is. – jonrsharpe Apr 24 '16 at 12:15
  • I'm not sure what's the objective in here. You can do this through a simple generator as defined in `get_primes1`. You would do the alternative essentially when you need to promise the next output, typically in `callback` functions. Also, you should normally use `.next()` beforehand. Here, there is no point to it since you are passing a variable (`number`) to your function anyway! – Pouria Apr 24 '16 at 12:17
  • Check this out: https://stackoverflow.com/questions/19302530/python-generator-send-function-purpose – Pouria Apr 24 '16 at 12:20

1 Answers1

2

how the send function work in generator?

def counter():
    total = 0

    while True:
        increment = yield total  #If next() was called, 
                                 #increment is assigned None. 
                                 #If send() was called,
                                 #increment is assigned send()'s argument.

        if increment:
            total += increment
        else:
            total += 1


g = counter()
print(next(g))
print(next(g))
print(g.send(3))
print(next(g))

--output:--
0
1
4
5

A yield expression's value is None whenever the generator is resumed by a normal next() call.


send() method for generator-iterators, which resumes the generator and "sends" a value that becomes the result of the current yield-expression. The send() method returns the next value yielded by the generator

See PEP 342

but b.send(1) still return the same value.why there is difference?

Because you are resetting number to the value of send()'s argument over and over again:

a:  number = 2
    number += 1
    number += 1

b:  number = 2
    number = 1
    number += 1
    number = 1
    number += 1
7stud
  • 46,922
  • 14
  • 101
  • 127