Ovi
Ovi

Reputation: 573

Why does this function return a value when there is no call to return?

I have the following example in my book, which is supposed to be a program whch calculates the new balance after interest is added on multiple accounts:

def addInterest(balances, rate):
    for i in range (len(balances)):
    balances[i] = balances[i] * (1 + rate)


def test():
    amounts = [1000, 2200, 800, 360]
    rate = 0.05
    addInterest(amounts, rate)
    print(amounts)


test()

The output is [1050.0, 2310.0, 840.0, 378.0]

There is no return call at the end of addInterest, so why doesn't print(amounts) just print amounts which was defined intially, namely [1000, 2200, 800, 360]?

Upvotes: 2

Views: 93

Answers (4)

Geeocode
Geeocode

Reputation: 5797

Because lists are mutable and balances[i] = balances[i] * (1 + rate modified the values of amounts too, which was passed with the call addInterest(amounts, rate)

Thus addInterest() has an implicit return value in this case.

Upvotes: 1

krethika
krethika

Reputation: 4476

See this post about data model and in particular the part about mutability.

Here is an example of how lists are mutable

>>> arr = [1,2,3]
>>> arr[0] = 99
>>> print(arr)
[99, 2, 3]

When you call the addInterest function, passing the amounts array as a parameter, it modified that array. Here's another example showing how that occurs

def test(my_list):
    print(my_list)
    my_list[0] = 99
    print(my_list)

Now test in the interpreter

>>> arr = [1,2,3]
>>> x = test(arr)
[1,2,3] 
[99, 2, 3]
>>> arr
[99,2,3]
>>> x
>>> x is None
True

So you can see, the return value of the function is None, which we stored in the variable named x. But the function also has a side effect, which is to change the value of the list arr that was passed into it.

Finally, let's see an example like yours, where the array is defined inside a function.

def change_list(l):
    print(l)
    l[0] = 99
    print(l)


def test():
    arr = [1,2,3]
    change_list(arr)

and check it out in the interpreter

>>> x = test()
[1, 2, 3]
[99, 2, 3]
>>> x
>>> x is None
True

Hope this clears up any confusion.

Upvotes: 1

Christian Tapia
Christian Tapia

Reputation: 34146

Indeed, when no return is specified, None is returned by default. But, why are you getting other values? Because when you do this

balances[i] = balances[i] * (1 + rate)

you are modifying the values of the list balances.

So, you are doing the following:

  1. Declare the list amounts = [1000, 2200, 800, 360]
  2. Call the function addInterest passing the list as a parameter. Inside this function you are modifying the content of this list. You don't return anything, but the list is already modified.
  3. You print the modified list and the new values are shown.

Upvotes: 2

stellasia
stellasia

Reputation: 5612

Your function does not return anything, but it prints the result. If you just do :

def test():
    amounts = [1000, 2200, 800, 360]
    rate = 0.05
    addInterest(amounts, rate)

then test() will be None (which is the default return value of a function).

If you want your function to return a result, you have to change the print to a return like this :

def test():
    amounts = [1000, 2200, 800, 360]
    rate = 0.05
    addInterest(amounts, rate)
    return amount

Also, be careful when modifying a list in a function. See for example https://stackoverflow.com/a/17686659/4709400

Upvotes: 1

Related Questions