Python language basics 64: a basic example of yield generators

Introduction

In the previous post we looked at the continue keyword in Python. We saw how it helped us stop the execution of a loop in case the current value of the iteration wasn’t to be handled in the same way as others.

In this post we’ll look at something completely different: the somewhat odd language construct of yielding a value.

The English word ‘yield‘ means approximately ‘produce’ or ‘give way’. A good investment can yield a high return. A fertile field can yield a lot of corn.

Yielding in Python

The yield keyword in Python is similar in usage. It is used in conjunction with loops that are lazily evaluated, where lazy means ‘on demand’ so that no memory is occupied unless the function is evaluated by the caller. Also, the function that yields a value – called a generator function – “remembers” the state from the previous execution. This all may sound mysterious. The usage of the yield keyword is definitely confusing at first I think.

C# has also a yield keyword and it works similar to how it does in Python. I’m not aware of any equivalent in Java.

You can think of generator functions as collections, or iterables. Iterables are objects that can be iterated, just like collections, in a for-each loop. A function which has the yield keyword automatically becomes a generator function that can be called in a for-each loop. Generator functions cannot be called and executed like “normal” functions.

Here’s a normal integer list with an iterator:

integers = [1, 2, 3, 4]
for i in integers:
    print('Printing ', i)

Here’s the output:

Printing 1
Printing 2
Printing 3
Printing 4

Here’s the generator function equivalent of the above code:

def integer_yielder():
    yield 1
    yield 2
    yield 3
    yield 4

integers = integer_yielder()
for i in integers:
    print('Printing ', i)

We have a generator function with 4 yield statements. You can think of yield statements really as yield return statements. The above generator function has 4 yield return statements. It will return 1 in the first iteration and “remember” that it has already returned 1. In the next iteration it returns 2 and so on until there are no more elements to be “yielded”.

Notice how we assign integer_yielder to a variable just like we assigned an integer list to it previously. The key difference is that the integer list was loaded into memory at the moment of the variable assignment. Generator functions on the other hand are evaluated lazily in a just-in-time manner, meaning that the integers 1, 2, 3 and 4 yielded by the function are not loaded into memory. First only ‘1’ is loaded when the iteration starts, and then 2, 3 and finally 4.

This second version has the exact same printout as the first.

In the next post we’ll see how yield generators can keep the state of their variables from one iteration to another.

Read all Python-related posts on this blog here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: