-4

I was getting confused by the purpose of "return" and "yield"

def countMoreThanOne():
    return (yy for yy in xrange(1,10,2))

def countMoreThanOne():
    yield (yy for yy in xrange(1,10,2))

What is the difference on the above function? Is it impossible to access the content inside the function using yield?

Anentropic
  • 32,188
  • 12
  • 99
  • 147
gostriderful
  • 99
  • 1
  • 7
  • 2
    possible duplicate of [Python: generator expression vs. yield](http://stackoverflow.com/questions/1995418/python-generator-expression-vs-yield) – fredtantini Nov 19 '14 at 11:50
  • 1
    in short - you are returning a generator of generator (with 1 element) in second function and a generator in first function. – Rusty Nov 19 '14 at 11:52
  • what do you mean "Is it impossible to access the content inside the function using yield?" ? – Anentropic Nov 19 '14 at 12:37
  • when you use the `yield` keyword in a function it becomes a generator function - when you call it you get a generator back. So by yielding a generator expression in the second example you've made a generator inside a generator https://wiki.python.org/moin/Generators – Anentropic Nov 19 '14 at 12:43
  • @Anentropic Thanks for clearing the idea behind the second example, I was try to create a function which aim to use only generator then list for returning the result. Since I saw most of the example of using generator are come up with `yield`. – gostriderful Nov 19 '14 at 13:57
  • it would be better to just write the function as `def countMoreThanOne(): return xrange(1,10,2)` ...an [xrange object](https://docs.python.org/2/library/stdtypes.html#typesseq-xrange) is iterable and has much the same benefit of a generator (constant memory usage no matter how big the sequence) – Anentropic Nov 19 '14 at 14:03
  • Does this answer your question? [What does the "yield" keyword do?](https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do) – Willy satrio nugroho Nov 19 '21 at 02:48

2 Answers2

4

In first you return a generator

from itertools import chain
def countMoreThanOne():
    return (yy for yy in xrange(1,10,2))

print list(countMoreThanOne())

>>> 
[1, 3, 5, 7, 9]

while in this you are yielding a generator so that a generator within the generator

def countMoreThanOne():
    yield (yy for yy in xrange(1,10,2))

print list(countMoreThanOne())
print list(chain.from_iterable(countMoreThanOne()))

 [<generator object <genexpr> at 0x7f0fd85c8f00>]
[1, 3, 5, 7, 9]

if you use list comprehension then difference can be clearly seen:-

in first:-

def countMoreThanOne():
    return [yy for yy in xrange(1,10,2)]
print countMoreThanOne()

>>> 
[1, 3, 5, 7, 9]

def countMoreThanOne1():
    yield [yy for yy in xrange(1,10,2)]
print countMoreThanOne1()

<generator object countMoreThanOne1 at 0x7fca33f70eb0>
>>>
Vishnu Upadhyay
  • 5,043
  • 1
  • 13
  • 24
0

After reading your other comments I think you should write the function like this:

def countMoreThanOne():
    return xrange(1, 10, 2)


>>> print countMoreThanOne()
xrange(1, 11, 2)
>>> print list(countMoreThanOne())
[1, 3, 5, 7, 9]

or even better, to have some point in making it a function:

def oddNumbersLessThan(stop):
    return xrange(1, stop, 2)


>>> print list(oddNumbersLessThan(15))
[1, 3, 5, 7, 9, 11, 13]
Anentropic
  • 32,188
  • 12
  • 99
  • 147