Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Multiple Return Values

00:00 In this lesson and the next, you’ll see how you can use Python to mimic some of the functionality other programming languages provide using pass by reference.

00:09 I’ll be following Marius’s tutorial a little more closely for a while, so feel free to follow along as well if that’s what you’d like to do, I’ll still, however, do my examples in C++ instead of C#.

00:23 Hopefully, I’ve successfully demonstrated some advantages to pass by reference. Now you’ll see how Python can be used to implement some of those most significant advantages.

00:35 First, you’ll look at object duplication, or rather the lack thereof.

00:40 You saw how by using pass by reference, you can avoid the issue of memory duplication and the time involved in copying a complex object or structure from an argument variable to a parameter variable.

00:54 But Python does almost the same thing. When you use an object as an argument, the parameter name is bound to that same object. Python doesn’t make a copy of the object, even for the simplest data types, so that benefit is already provided by Python’s pass by assignment mechanism.

01:15 So, let’s take a look at another: creating multiple return values. As I’ve mentioned, many languages allow only for a single return value from a function.

01:27 So programmers of that language have had to improvise if they need two or more different pieces of information given back from a function to the calling environment.

01:37 So what they would usually do is use the actual return value for one of them and pass another variable argument by reference and let the function give it a value, which is then retained and can be used once the function ends.

01:53 As an example, consider a program that’s to create a personalized greeting and update a count of how many times it’s been used. Here’s a version in C++. It takes one parameter, the name, to personalize the greeting, and then a reference parameter to update the count of how many times the function has been called.

02:19 You can see the ampersand (&) in front of the word counter to indicate that this is being passed by reference. A greeting is created by appending the provided name to the word "Hi, ".

02:32 The counter is incremented, and since this was provided using pass by reference, the associated argument variable will be incremented by this statement as well.

02:44 The greeting is then returned. This main() function shows how it’s used. It creates a counter variable called count, which will keep track of how many times the function is called.

02:57 It is passed as the second argument in the function call. First in a function call that’s going to create a greeting for "Alice", which is then printed using C++’s cout statement. And then in one for Bob, it also displays the value of count after each greeting.

03:21 I can show you this working in a terminal window. First, I’ll compile it for you, then I’ll run it.

03:39 Here’s the greeting for Alice and then the updated value of count, the greeting for Bob, and the updated value of count again.

03:51 How would things work in Python? Well first, let’s look at what doesn’t work. This function in Python is nearly a line-by-line version of what you saw in C++.

04:03 As you can see, the function greet() takes two parameters, increments the counter, and returns the personalized greeting. The script creates a counter variable called count, prints the greeting personalized for Alice, passing count as the second parameter, displaying the value of count, then doing the same for Bob. Let’s take a look at this when it runs.

04:39 We see that count wasn’t updated. Why not?

04:46 Because the statement counter += 1 is an assignment statement, Python computes the value of counter using its current value plus 1, creates a new object with that computed value, then assigns—or rather, binds—that new object with the parameter variable counter.

05:07 The parameter variable no longer has any connection with the original object it was bound to. The variable count in the script is still bound to that object with a value of 0 and was unaffected by the parameter counter being bound to a new object. Again, this is pass by assignment. By assignment, counter was bound to the same object that count was bound to, but that was only until it was changed to be bound to something else. Its connection, or reference, to that original object was gone.

05:47 Of course, you don’t have to do this in Python because Python allows you to return multiple values. So you can, in a single return statement, return the personalized greeting and the incremented value of how many times the function has been called packed in a tuple.

06:07 So here is the newer version of the greet() function but with the same script using it. If I run it,

06:21 I see the updated value of counter is being returned, but the variable count isn’t being updated to use it. Also, printing the return value of this function is now displaying the entire tuple and not just the greeting that we had before.

06:44 The script needs to be modified to unpack the returned tuple so it can save the updated count. This new script now unpacks the returned tuple by storing each element to a separate variable.

06:57 The greeting is saved to the variable greeting and the updated counter value is saved back to the variable count. After displaying that information, the script then calls greet() a second time, this time for "Bob".

07:12 The same count variable is passed to that function call, and again, the return tuple is unpacked, saving the new greeting to greeting, and saving the updated counter value back to count. By the way, the only significance about saving the second greeting back to the same greeting variable is because the script no longer needs the greeting for "Alice". It’s already used it.

07:37 What you want to be watching is how the count variable is being used as an argument and the variable to save the modified counter from the returned tuple.

07:50 greet() returns the greeting and counter. The personalized greeting gets saved in the variable greeting, which is then printed.

08:00 The updated count is then printed. That happens for both "Alice" and "Bob".

08:16 And there, you can see the desired output. We print the greeting for "Alice", the updated count, the greeting for "Bob", and the updated count.

08:25 This is actually the exact same output the original C++ version of the program had.

08:35 Assigning return values to variables is the best way to achieve the same results as passing by reference in Python. You’ll see this again later. But next, you’ll look at how pass by reference can work with functions that return different things based on certain conditions within the function and how Python can be used to do that as well.

Become a Member to join the conversation.