1

I am reading John Zelle's Python programming 2ed Ch6. And I encounter a concept question: His example code says:

#addinterest3.py 
def addInterest(balances, rate):
    for i in range(len(balances)):
        balances[i] * (1 + rate)


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


test()

with upper code the

"assignments into the list caused it to refer to the new values. The old values will actually get cleaned up when Python does garbage collection"

According to this idea I tried a test.py

def add(balance, rate):
    balance = balance * (1 + rate)


def test():
    amount = 1000
    rate = 0.5
    amount = add(amount, rate)
    print(amount)


test()

I think the balance can also be assigned by a new values, but it turns out return "none" in my terminal. Can anyone explain what is the fundamental difference between them? Why list assignment dont need to use return to pass the value but will still be saved, on the other hand, my test.py do required a "return balance" after the function ?

4
  • is that your actual code? cause the indentation is completely wrong. Commented Apr 16, 2013 at 1:45
  • 1
    The code in addInterest has no side effects and no explicit return value. Specifically, balances[i]*(1+rate) does not modify any value. Given the code above, this is not correct: "assignments into the list caused it to referto the new values." There are no assignments into the list. That would require balances[i] *= (1+rate) Commented Apr 16, 2013 at 1:45
  • I just copy what is on the book. Commented Apr 16, 2013 at 4:11
  • See also: nedbatchelder.com/text/names1.html Commented Jun 5, 2022 at 16:50

3 Answers 3

1

The reason you are not getting any value in amount is because your add function is not returning anything.

def add(balance,rate):
    return balance*(1+rate)

Would return a value which would be assigned to amount.

Added to that, the beginning code is wrong. If you we're to try this code in python you would find that it prints out:

[1000, 2200, 800, 360]

it needs to be changed to:

def addInterest(balances,rate):
    for i in range(len(balances)):
        balances[i] = balances[i]*(1+rate)
Sign up to request clarification or add additional context in comments.

2 Comments

I think my problem is why if the parameters in function have to be passed by value but if the variable is a list then you will find out your "object change" become "visible" in your result.(Sorry i am a novice and not good at english yet this problem really confuses me)
Python does not pass every parameter as a reference, only lists and the like. So even if you did add(amount, rate) the amount will not change. Appart from that, you cant assign amount to the return of a non-returning function, it will just put in a None. If the code in your question was in that book, Do not use that book learn from Learn Python the Hard Way
1

As I may expect, if you pass a list as a function argument it like you pass the pointer on this list. Assignment statements in Python do not copy objects, they create bindings between a target and an object. Therefore if you change the list inside the function you can see these changes. If you pass the variables, the copies of these variables are used inside the function.
As an example you can also try this code:

a = [1, 2]
b = a
a.append(3)
print a, b

Output:

[1, 2, 3] [1, 2, 3]

Ups!

Comments

0

Your add function doesn't return anything, so Python automatically has it return None at the end. When you write:

amount = add(amount,rate)

add returns None, so amount is set to None.

Also, not all objects in Python are mutable, so modifying the variable from inside of the function won't do what you expect. Use return instead:

def add(balance,rate):
    return balance * (1 + rate)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.