473,395 Members | 1,637 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,395 software developers and data experts.

yield

km
Hi all,

i didnt understand the purpose of 'yield' keyword and the concept of 'generators' in python. can someone explain me with a small example how generators differ from normal function calls?
kindly enlighten
regards,
KM


Jul 18 '05 #1
3 2750
km wrote:
Hi all,

i didnt understand the purpose of 'yield' keyword and the concept of 'generators' in python. can someone explain me with a small example how generators differ from normal function calls?
kindly enlighten
regards,
KM


I think of it as an "interrupt" that provides a value back to the caller
for each value in a sequence. It can also be loosely thought of as an
iterator(sort of).

Here's an example that may (or may not) help:
def foo():
print 'entering foo function'
for i in range(3):
print 'yielding %s' % i
yield i
print 'leaving foo function'

for x in foo():
print 'x is %s' % x

################
prints out the following:

entering foo function
yielding 0
x is 0
yielding 1
x is 1
yielding 2
x is 2
leaving foo function

Jul 18 '05 #2
>>>>> "km" == km <km@mrna.tn.nic.in> writes:

km> Hi all, i didnt understand the purpose of 'yield' keyword and the
km> concept of 'generators' in python. can someone explain me with a
km> small example how generators differ from normal function calls?

Normally, when you define a function and call it, the code within the
function gets executed, until the function returns, and at that point the
function disappear altogether. For example:
def f(): .... a = 1
.... while a < 32:
.... print 'Hello, ' + str(a)
.... return a
.... a *= 2
.... f() Hello, 1
1

Here we define f, and at the time of definition the statements of the
function won't be executed. Instead it is executed when the function is
called. Once the function returns, the function disappear completely, with
all the context in the function: all the statements after the return
statement (a*=2 here) won't be executed, and the "other iterations" of the
loop will no longer execute. Here, after printing 'Hello, 1', the function
stops, returning a value 1 to the caller (which is printed by the Python
interpretor).

When a function contains the "yield" keyword, the story is somewhat
different. If we simply replace the "return" keyword with the "yield"
keyword in the above example we get this:
def f(): .... a = 1
.... while a < 32:
.... print 'Hello, ' + str(a)
.... yield a
.... a *= 2
.... f() <generator object at 0x4022136c>

In other words, the statements within the function will not be invoked even
when we call f()! Instead, calling f() returns you an object, which is said
to be a "generator" object. The basic method of this object is "next". For
example:
g = f()
g.next() Hello, 1
1

So, the effect of f().next() in the function using "yield" is exactly the
same as f() in the function using "return". The difference in the current
version is that we still have an object g, so... we can call next() again!
g.next() Hello, 2
2 g.next() Hello, 4
4 g.next() Hello, 8
8 g.next() Hello, 16
16 g.next() Traceback (most recent call last):
File "<stdin>", line 1, in ?
StopIteration

In other words, after the function f yields, the function and the execution
context has not disappear. Instead it is still stored within the generator
object, waiting for you to call next() again. At that point the function
continues its execution. If during the execution the function yields
another value, g.next() returns the value of that value and f is stopped
again. If during the execution the function returns, g.next() throws an
exception StopIteration (and will do that again if you call g.next() again).

This is a powerful construct: this is the only Python construct that let you
easily "remember" the dynamic execution structure. (Most other language
lacks that facility so it is impossible to remember the dynamic execution
structure, short of packaging all the information you want in structure.)
In the above example, after the first execution of next(), the g object
remembers (in its "frame object", which can be located by g.gi_frame) what
local variables are defined and what values they hold, which line the
function is currently executing at, and what global variables are currently
visible:
g = f()
g.next() Hello, 1
1 dir(g.gi_frame) ['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'f_back', 'f_builtins', 'f_code', 'f_exc_traceback', 'f_exc_type', 'f_exc_value', 'f_globals', 'f_lasti', 'f_lineno', 'f_locals', 'f_restricted', 'f_trace'] g.gi_frame.f_locals {'a': 1} g.gi_frame.f_lineno 5 g.gi_frame.f_globals {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'g': <generator object at 0x4022146c>, 'f': <function f at 0x40219f44>}

The simplest way to use the construct, and also by far the most common use
of it, is to use it as an "iterator", i.e., to repeatedly call it in a loop
until it finishes throw a StopIteration exception. E.g.,
for i in f(): .... print i * 3 + 7
....
Hello, 1
10
Hello, 2
13
Hello, 4
19
Hello, 8
31
Hello, 16
55

Here the "for" loop will call the next() method of the generator returned by
f() repeatedly, each time getting the returned value into the variable i and
execute the "body" of the for loop (which prints the value i*3+7). Similar
things happen in list-comprehensions:
[i * 3 + 7 for i in f()]

Hello, 1
Hello, 2
Hello, 4
Hello, 8
Hello, 16
[10, 13, 19, 31, 55]

Note that, apart from printing the 'Hello, n' messages, both of the above
have the end-effect that f() is the list [1, 2, 4, 8, 16]. So you can treat
a generator as a "lazy" list that (1) an element will be generated
"on-the-fly" when next() is called, and thus may be affected by the changes
in the environment like the global variables, and may in reverse affect the
environment like printing message and changing the global variables; and (2)
after producing the element, the element itself will not be kept by the
generator.

Regards,
Isaac.
Jul 18 '05 #3
Isaac To <kk**@csis.hku.hk> writes:
>> "km" == km <km@mrna.tn.nic.in> writes:


km> Hi all, i didnt understand the purpose of 'yield' keyword and the
km> concept of 'generators' in python. can someone explain me with a
km> small example how generators differ from normal function calls?

Normally, when you define a function and call it, the code within the
function gets executed, until the function returns, and at that point the
function disappear altogether. For example:

[...]

That's a misleading way of putting it: the *function* doesn't
disappear (you can still call it after it's finished), but its state
of execution does (you can't access its local variables after it's
finished, except by calling it again and getting a *new* set of local
variables).
John
Jul 18 '05 #4

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():
22
by: Mateuszk87 | last post by:
Hi. may someone explain "yield" function, please. how does it actually work and when do you use it? thanks in forward mateusz
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):
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
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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...
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...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.