473,385 Members | 1,553 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Yield

Hi.

may someone explain "yield" function, please. how does it actually work
and when do you use it?

thanks in forward

mateusz

Nov 15 '06 #1
22 2178
Mateuszk87 wrote:
may someone explain "yield" function, please. how does it actually work
and when do you use it?
it returns a value from a function without actually terminating the
function; when the function is resumed, it'll continue to execute after
the yield.

a function that contains a yield statement is called a "generator", and
is most often used in a for-in loop, or in other contexts that expect a
sequence. the loop is automatically terminated when the function
returns in a usual way:
>>def gen():
.... yield 1
.... yield 2
.... yield 3
....
>>for item in gen():
.... print item
....
1
2
3
>>sum(gen())
6
>>[str(i) for i in gen()]
['1', '2', '3']

you can also use the generator "by hand"; when you call a generator
function, it returns a special "generator object", and then immediately
suspends itself. to run the generator, call its "next" method:
>>g = gen()
g
<generator object at 0x00AE64E0>
>>g.next()
1
>>g.next()
2
>>g.next()
3

when the generator is exhausted, it raises a StopIterator exception:
>>g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

reference information:

http://effbot.org/pyref/yield.htm

hope this helps!

</F>

Nov 15 '06 #2
Fredrik Lundh wrote:
reference information:
also see:

http://effbot.org/pyfaq/what-is-a-generator.htm

</F>

Nov 15 '06 #3
On Wed, 2006-11-15 at 09:13 -0800, Mateuszk87 wrote:
Hi.

may someone explain "yield" function, please. how does it actually work
and when do you use it?
[There is probably a much better explanation of this somewhere on the
net already, but I feel like writing this out myself.]

"yield" is a keyword. In simple terms, if "yield" appears inside a
function, the function becomes a generator that can return multiple
results.

Consider the following trivial example of a function that calculates the
elements of some sequence and prints each one.

def squares(n):
for i in range(n):
print i**2

Now suppose it turns out that in addition to--or instead of--printing
the elements of this sequence, the caller wants to do something
different with them. You could handle this by building a list, and
return the list to the caller to loop over and operate on as they
choose. But if the list is very big, that's not very memory-efficient if
the caller only needs to operate on one element at a time.

This is where yield comes in. If you write this:

def squares(n):
for i in range(n):
yield i**2

squares is now a generator function. If you call squares(100), it won't
calculate any sequence elements immediately. It will instead return an
iterator the caller can loop over:

for el in squares(100):
print el # or do anything else the caller decides

The beauty of this is that you achieve physical separation between
generating elements of a sequence and using them. The generator function
only cares about how to produce the elements, and the caller only cares
about how to use them.

Hope this helps,

Carsten.
Nov 15 '06 #4
thx for the quick answer. i ll have a look.

Nov 15 '06 #5
Thank you. This is very clear. I can see that this is useful in lots
of situations.

Fredrik Lundh wrote:
Mateuszk87 wrote:
may someone explain "yield" function, please. how does it actually work
and when do you use it?

it returns a value from a function without actually terminating the
function; when the function is resumed, it'll continue to execute after
the yield.

a function that contains a yield statement is called a "generator", and
is most often used in a for-in loop, or in other contexts that expect a
sequence. the loop is automatically terminated when the function
returns in a usual way:
>>def gen():
... yield 1
... yield 2
... yield 3
...
>>for item in gen():
... print item
...
1
2
3
>>sum(gen())
6
>>[str(i) for i in gen()]
['1', '2', '3']

you can also use the generator "by hand"; when you call a generator
function, it returns a special "generator object", and then immediately
suspends itself. to run the generator, call its "next" method:
>>g = gen()
>>g
<generator object at 0x00AE64E0>
>>g.next()
1
>>g.next()
2
>>g.next()
3

when the generator is exhausted, it raises a StopIterator exception:
>>g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

reference information:

http://effbot.org/pyref/yield.htm

hope this helps!

</F>
Nov 15 '06 #6
Mateuszk87 wrote:
Hi.

may someone explain "yield" function, please. how does it actually work
and when do you use it?

thanks in forward

mateusz
http://docs.python.org/ref/yield.html
Nov 16 '06 #7

dwelch91 a écrit :
http://docs.python.org/ref/yield.html
This is a perfect example that demonstrate how the actual python is bad
and most of the time useless (at least for me).

We really need mor example !

I would like to thanks Fredrik for his contribution to improve that.

Olivier.

Nov 16 '06 #8
On 16/11/2006 5:45 PM, olive wrote:
dwelch91 a écrit :
>http://docs.python.org/ref/yield.html

This is a perfect example that demonstrate how the actual python is bad
and most of the time useless (at least for me).
I think that you left the word "documentation" out after "python" :-)
>
We really need mor example !

I would like to thanks Fredrik for his contribution to improve that.
Call me crazy, but after an admittedly quick read, the version on the
wiki seems to be about word for word with on the docs.python.org version.

Could you please tell us how you think the wiki version is an improvement?

Cheers,
John
Nov 16 '06 #9
olive wrote:
>http://docs.python.org/ref/yield.html

This is a perfect example that demonstrate how the actual python is bad
and most of the time useless (at least for me).
there's a place for (relatively) formal reference documentation, but
it's hardly ever the right place to learn why things are there, or how
they are supposed to be used.
We really need mor example !

I would like to thanks Fredrik for his contribution to improve that.
thanks!

(for the curious, my current plan is to use

http://effbot.org/zone/idea-seealso.htm

files to link from the official documentation to tutorials, example
collections, and blog articles. I encourage content producers to start
looking into generating such files for their document collections.)

</F>

Nov 16 '06 #10
John Machin wrote:
>I would like to thanks Fredrik for his contribution to improve that.

Call me crazy, but after an admittedly quick read, the version on the
wiki seems to be about word for word with on the docs.python.org version.
maybe he was thinking about the article I posted, or the FAQ link I
posted in a followup:

http://effbot.org/pyfaq/what-is-a-generator.htm

which was based on my article and the glossary entry from the tutorial:

http://effbot.org/pytut/glossary.htm#generator
Could you please tell us how you think the wiki version is an improvement?
an "add comment" link? direct URL:s for all concepts in the language?
extensive hyperlinking? semantic retargetable markup?

</F>

Nov 16 '06 #11
On 16/11/2006 7:00 PM, Fredrik Lundh wrote:
John Machin wrote:
>>I would like to thanks Fredrik for his contribution to improve that.

Call me crazy, but after an admittedly quick read, the version on the
wiki seems to be about word for word with on the docs.python.org version.

maybe he was thinking about the article I posted, or the FAQ link I
posted in a followup:

http://effbot.org/pyfaq/what-is-a-generator.htm

which was based on my article and the glossary entry from the tutorial:

http://effbot.org/pytut/glossary.htm#generator
Quite possibly.
>
>Could you please tell us how you think the wiki version is an
improvement?

an "add comment" link? direct URL:s for all concepts in the language?
extensive hyperlinking? semantic retargetable markup?
Yes, they're great. Maybe I was thinking about the text contents only :-)

Cheers,
John
Nov 16 '06 #12
Now that we're on the subject, what are the advantages of using
generators over, say, list comprehensions or for loops? It seems to me
that virtually all (I won't say everything) the examples I've seen can
be done just as easily without using generators. For example,
Fredrik's initial example in the post:
>>a = [1,2,3]
for i in a: print i
....
1
2
3
>>sum(a)
6
>>[str(i) for i in a]
['1', '2', '3']
>>>
Carsten mentioned that generators are more memory-efficient to use when
dealing with large numbers of objects. Is this the main advantage of
using generators? Also, in what other novel ways are generators used
that are clearly superior to alternatives?

Thanks in advance,

Danny

On Nov 16, 3:14 am, John Machin <sjmac...@lexicon.netwrote:
On 16/11/2006 7:00 PM, Fredrik Lundh wrote:
John Machin wrote:
>I would like to thanks Fredrik for his contribution to improve that.
Call me crazy, but after an admittedly quick read, the version on the
wiki seems to be about word for word with on the docs.python.org version.
maybe he was thinking about the article I posted, or the FAQ link I
posted in a followup:
http://effbot.org/pyfaq/what-is-a-generator.htm
which was based on my article and the glossary entry from the tutorial:
http://effbot.org/pytut/glossary.htm#generatorQuite possibly.


Could you please tell us how you think the wiki version is an
improvement?
an "add comment" link? direct URL:s for all concepts in the language?
extensive hyperlinking? semantic retargetable markup?Yes, they're great. Maybe I was thinking about the text contents only :-)

Cheers,
John
Nov 16 '06 #13

"Danny Colligan" <da***********@gmail.comwrote in message
news:11**********************@i42g2000cwa.googlegr oups.com...
Now that we're on the subject, what are the advantages of using
generators over, say, list comprehensions or for loops? It seems to me
that virtually all (I won't say everything) the examples I've seen can
be done just as easily without using generators.
The more trivial the example, the harder it is to see the advantage.
Suppose you wanted to sum the first 10000 primes. A quick Google
fins you Wensheng Wang's recipe:
http://aspn.activestate.com/ASPN/Coo.../Recipe/366178
Just add print sum(primes(10000)), and you're done.


Nov 16 '06 #14
The more trivial the example, the harder it is to see the advantage.

I absoultely agree. Thanks for pointing me out to some real-world
code. However, the function you pointed me to is not a generator
(there is no yield statement... it just returns the entire list of
primes). A generator version would be:
>>def primes(n):
.... if n<2: yield []
.... s=range(3,n+1,2)
.... mroot = n ** 0.5
.... half=(n+1)/2-1
.... i=0
.... m=3
.... while m <= mroot:
.... if s[i]:
.... j=(m*m-3)/2
.... s[j]=0
.... while j<half:
.... s[j]=0
.... j+=m
.... i=i+1
.... m=2*i+3
.... yield 2
.... for x in s:
.... if x: yield x
....
>>x = primes(11)
x.next()
2
>>x.next()
3
>>x.next()
5
>>x.next()
7
>>x.next()
11
>>x.next()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
StopIteration
>>>
Danny Colligan

On Nov 16, 10:49 am, "Richard Brodie" <R.Bro...@rl.ac.ukwrote:
"Danny Colligan" <dannycolli...@gmail.comwrote in messagenews:11**********************@i42g2000cwa.g ooglegroups.com...
Now that we're on the subject, what are the advantages of using
generators over, say, list comprehensions or for loops? It seems to me
that virtually all (I won't say everything) the examples I've seen can
be done just as easily without using generators.The more trivial the example, the harder it is to see the advantage.
Suppose you wanted to sum the first 10000 primes. A quick Google
fins you Wensheng Wang's recipe:http://aspn.activestate.com/ASPN/Coo.../Recipe/366178
Just add print sum(primes(10000)), and you're done.
Nov 16 '06 #15
On Thu, 2006-11-16 at 07:32 -0800, Danny Colligan wrote:
Carsten mentioned that generators are more memory-efficient to use when
dealing with large numbers of objects. Is this the main advantage of
using generators? Also, in what other novel ways are generators used
that are clearly superior to alternatives?
The memory efficiency is definitely a major advantage. Generators allow
you to efficiently produce, manipulate, and consume sequences of
arbitrary length. The length of the sequence could even be potentially
infinite, which is impossible to handle when you're working with actual
lists.

The memory efficiency aside, it's more elegant to write something like
this:

def squares(n):
for i in range(n):
yield i**2

than something like this:

def squares(n):
result = []
for i in range(n):
result.append(i**2)
return result

-Carsten
Nov 16 '06 #16
On Thu, 2006-11-16 at 08:09 -0800, Danny Colligan wrote:
The more trivial the example, the harder it is to see the advantage.

I absoultely agree. Thanks for pointing me out to some real-world
code. However, the function you pointed me to is not a generator
(there is no yield statement... it just returns the entire list of
primes). A generator version would be:
>def primes(n):
... if n<2: yield []
... s=range(3,n+1,2)
... mroot = n ** 0.5
... half=(n+1)/2-1
... i=0
... m=3
... while m <= mroot:
... if s[i]:
... j=(m*m-3)/2
... s[j]=0
... while j<half:
... s[j]=0
... j+=m
... i=i+1
... m=2*i+3
... yield 2
... for x in s:
... if x: yield x
Not quite:
>>x = primes(1)
x.next()
[]
>>x.next()
2
>>x.next()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
StopIteration

To handle n<2 correctly, you have to "return" instead of "yield []".
>>x = primes(1)
x.next()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
StopIteration

-Carsten
Nov 16 '06 #17

"Danny Colligan" <da***********@gmail.comwrote in message
news:11*********************@b28g2000cwb.googlegro ups.com...
I absoultely agree. Thanks for pointing me out to some real-world
code. However, the function you pointed me to is not a generator
(there is no yield statement... it just returns the entire list of
primes).
Oops, should have looked at the code more closely. Another example
would be os.walk() in the standard library.
Nov 16 '06 #18
>I absoultely agree. Thanks for pointing me out to some real-world
>code. However, the function you pointed me to is not a generator
(there is no yield statement... it just returns the entire list of
primes).

Oops, should have looked at the code more closely. Another example
would be os.walk() in the standard library.
I've used a similar scheme for dealing with incoming data files.
Sometimes, I get them Emailed/FTP'ed so they're sitting in a
folder, so I can do a multitude of them by just pointing
os.walk() at them. Other times, I get them on specially
formatted CDs. It's nice to have the clean main-loop logic of:

for file_name in source:
do_stuff(file_name)

and be able to dynamically set "source" to an generator that
either wraps os.walk() for a given directory or repeatedly (1)
reads the file on the CD to know where it should be dumped, (2)
copies files off the CD to their associated dumping ground, (3)
ejects the CD, (4) yields the name of the file to process in the
dumping-ground directory, and (5) prompts the user if there are
more CDs to be processed.

Without "yield" functionality, I'd either have to have two
duplicate loops with similar internal logic (the do_stuff() sort
of code), or I'd have to read in all the files off the CD and
*then* process them all as a list afterwards.

Just one of the places I've recently been thankful for generators.

-tkc

Nov 16 '06 #19
Danny Colligan wrote:
Carsten mentioned that generators are more memory-efficient to use when
dealing with large numbers of objects. Is this the main advantage of
using generators? Also, in what other novel ways are generators used
that are clearly superior to alternatives?
the main advantage is that it lets you decouple the generation of data
from the use of data; instead of inlining calculations, or using a pre-
defined operation on their result (e.g printing them or adding them to a
container), you can simply yield them, and let the user use whatever
mechanism she wants to process them. i.e. instead of

for item in range:
calculate result
print result

you'll write

def generate():
for item in range:
yield result

and can then use

for item in generate():
print item

or

list(process(s) for s in generate())

or

sys.stdout.writelines(generate())

or

sum(generate())

etc, without having to change the generator.

you can also do various tricks with "endless" generators, such as the
following pi digit generator, based on an algorithm by Python's grand-
father Lambert Meertens:

def pi():
k, a, b, a1, b1 = 2, 4, 1, 12, 4
while 1:
# Next approximation
p, q, k = k*k, 2*k+1, k+1
a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
# Yield common digits
d, d1 = a/b, a1/b1
while d == d1:
yield str(d)
a, a1 = 10*(a%b), 10*(a1%b1)
d, d1 = a/b, a1/b1

import sys
sys.stdout.writelines(pi())

</F>

Nov 17 '06 #20
Fredrik Lundh schrieb:
Danny Colligan wrote:
>Carsten mentioned that generators are more memory-efficient to use when
dealing with large numbers of objects. Is this the main advantage of
using generators? Also, in what other novel ways are generators used
that are clearly superior to alternatives?

the main advantage is that it lets you decouple the generation of data
from the use of data; instead of inlining calculations, or using a pre-
defined operation on their result (e.g printing them or adding them to a
container), you can simply yield them, and let the user use whatever
mechanism she wants to process them. i.e. instead of

for item in range:
calculate result
print result

you'll write

def generate():
for item in range:
yield result

and can then use

for item in generate():
print item

or

list(process(s) for s in generate())

or

sys.stdout.writelines(generate())

or

sum(generate())

etc, without having to change the generator.

you can also do various tricks with "endless" generators, such as the
following pi digit generator, based on an algorithm by Python's grand-
father Lambert Meertens:

def pi():
k, a, b, a1, b1 = 2, 4, 1, 12, 4
while 1:
# Next approximation
p, q, k = k*k, 2*k+1, k+1
a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
# Yield common digits
d, d1 = a/b, a1/b1
while d == d1:
yield str(d)
a, a1 = 10*(a%b), 10*(a1%b1)
d, d1 = a/b, a1/b1

import sys
sys.stdout.writelines(pi())

</F>
or fibonacci:

def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a+b

now get the first 10 ones:
>>from itertools import *
list(islice(fib(),10))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
or primes:

def primes():
yield 1
yield 2

p = 3
psofar = []

smallerPrimes = lambda: takewhile(lambda x: x+x <= p,psofar)

while True:
if all(p % n != 0 for n in smallerPrimes()):
psofar.append(p)
yield p

p += 2

etc.
Jan 9 '07 #21
Mathias Panzenboeck wrote:
def primes():
yield 1
yield 2
[snip rest of code]
Hmm... 1 is not a prime. See for instance

http://en.wikipedia.org/wiki/Prime_number

The definition given there is "In mathematics </wiki/Mathematics>, a
*prime number* (or a *prime*) is a natural number </wiki/Natural_number>
that has exactly two (distinct) natural number divisors
</wiki/Divisor>." The important part of the statement is "exactly
two...divisors", which rules out the number 1.

/MiO
Jan 10 '07 #22


I wrote:
The definition given there is "In mathematics </wiki/Mathematics>, a
*prime number* (or a *prime*) is a natural number
</wiki/Natural_numberthat has exactly two (distinct) natural number
divisors </wiki/Divisor>." The important part of the statement is
"exactly two...divisors", which rules out the number 1.
Or should I say: Thunderbird made me write:... Those freakin
</wiki/Mathematicsand </wiki/Natural_numberwas not visible before I
posted the thing. &%#&%#

/MiO
Jan 10 '07 #23

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: yyhhjj | last post by:
I created a test program to implement an iterator. First, I used 'yield break' in the iterator, it worked normally. Then, I simply used 'break' in the places of 'yield break', it still worked...
2
by: IntraRELY | last post by:
I know this isnt really a VB question per say, but is what I am developing in VB.NET and Excel is the only place that has provided direction. I wanted to ask the public if perhaps you could lend me...
3
by: andy.leszczynski | last post by:
Hi, I might understand why this does not work, but I am not convinced it should not - following: def nnn(): print 'inside' yield 1 def nn():
3
by: Ehsan | last post by:
hi coulde any one show me the usage of "yield" keyword specially in this example: """Fibonacci sequences using generators This program is part of "Dive Into Python", a free Python book for...
6
by: Shriphani | last post by:
Hello all, Let us say I have a function like this: def efficientFiller(file): worthless_list = pot_file = open(file,'r') pot_file_text = pot_file.readlines() for line in pot_file_text: if...
1
by: castironpi | last post by:
What if I say oath= yield or other= yield ?
13
by: Martin Sand Christensen | last post by:
Hi! First a bit of context. Yesterday I spent a lot of time debugging the following method in a rather slim database abstraction layer we've developed: ,---- | def selectColumn(self,...
7
by: Alex Bryan | last post by:
Okay, so i don't really understand the Yield thing and i know it is useful. I've read a few things about it but it is all programming jargon and so basically it is hard for me to understand. So can...
5
by: defn noob | last post by:
def letters(): a = xrange(ord('a'), ord('z')+1) B = xrange(ord('A'), ord('Z')+1) while True: yield chr(a) yield chr(B) Traceback (most recent call last):
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.