Calling a loop in a function

The 2nd question in the Python Code Challenges:Lists (Learn Python 3) asks us to create a function to append the sum of the last two elements in a list, and repeat three times.


def append_sum(lst):
lst.append(lst[-1] + lst[-2])
lst.append(lst[-1] + lst[-2])
lst.append(lst[-1] + lst[-2])
return lst

print(append_sum([1, 1, 2]))


This prints out [1, 1, 2, 3, 5, 8]

No issues with getting the intended result. However, I saw that I could achieve the same result using a loop and wanted to try it out.

I tried using a for loop like this but I can’t get it to work…:


for _ in range(3):
print(append_sum([1, 1, 2]))


What should I do?

Hi there, and welcome to the forums!

When you say it’s not working what is the problem exactly? Are you getting the wrong expected output, or are you getting errors, or are you just getting something a bit strange? If we know your exact problem it can help to diagnose the issue a bit better! Also good to know would be what your expected output is, do you just want the loop to put out the same list that the function does on it’s own?

Hello!

I got the expected output, it’s just that I’d like to know how to get the same output using loops instead.
I’d like the loop to repeat the function three times.

the function being a single line:
def append_sum(lst):
lst.append(lst[-1] + lst[-2])

What have you tried for the for loop to get the same output? It’s likely more helpful from me if I can help you see the issues in your own code rather than me giving where to go, especially if you’ve already given it a go!

I tried doing the following:


def append_sum(lst):
lst.append(lst[-1] + lst[-2])
return lst

for sum in range(3):
append_sum([1, 1, 2])


There was no error but nothing was printed.

Ah perfect! So there is a couple issues here I can see off the bat. Firstly, nothing is printing because there are no print statements, so that’s an easy one to fix! The function returns a value but you need to print that value out to actually see it in the console.

Secondly, unfortunately when it does print out it only prints out [1, 1, 2, 3] 3 times. The reason is you’re just calling append_sum([1, 1, 2]) 3 times from the loop and so it’s just doing that first calculation. There’s a couple of changes that could be done to fix this.

First change would be to move the loop inside of the function. So instead of looping after the function, the loop is part of the function, like so:

def append_sum(lst):
    for i in range(3):
        lst.append(lst[-1] + lst[-2])
    return lst

print(append_sum([1, 1, 2]))
# prints [1, 1, 2, 3, 5, 8]

This would use the same list to check and append to, meaning that the final print outside of the function gives you the expected result [1, 1, 2, 3, 5, 8]. You could also expand this function to take an argument which lets you change the number of sums you want, rather than having it hardcoded to 3, so it is flexible.

Another way I can think of would be using a recursive function. This is essentially using a loop, however you are calling the function inside of itself to create the looping behaviour, like so:

def append_sum(lst, n=0):
    if n == 3:
        return lst
    else:
        lst.append(lst[-1] + lst[-2])
        n += 1
        return append_sum(lst, n)

print(append_sum([1, 1, 2]))
# prints [1, 1, 2, 3, 5, 8]

If you haven’t studied recursive functions yet don’t worry so much about this one, just another way of looking at it.

Finally, if you want to do it like the way you have in your attempt, you would need to have some way of saving and feeding in the new lst variable, rather than a static one, like below:

def append_sum(lst):
    lst.append(lst[-1] + lst[-2])
    return lst

lst = [1, 1, 2]

for sum in range(3):
    lst = append_sum(lst)

print(lst)
# prints [1, 1, 2, 3, 5, 8]

This works fine, but the issue I have with this ones execution is that it’s less self contained. You need to define your initial list and print the list after the loop all outside of the function, which isn’t a big deal but personally I prefer keeping variables related to the function as contained as possible. Any one of these solutions above can be implemented to do how you wanted and I’m sure there’s more you can think of too! I’ve blurred in case you want the explanations without the code to try yourself first also.

Hopefully that answers your question, do let me know if there’s anything else!

1 Like

Thank you so much for your detailed explanation! :grinning: It’s all explained super clearly and I understand where I’ve gone wrong now. The bit I’m a little confused about is on recursive functions but that’s just because I’ve just started learning python so I haven’t learned that yet.

That’s alright! Recursive functions are a bit of an advanced topic as they can get a little confusing, however they can be a nice alternative to loops sometimes. When you come up to them you at least now have something you can revisit to put it in context to something you do know, functions and loops, and see how it operates!

1 Like

Hope you don’t me asking another question!
Why is it that the outcome is not the same if we were to just put the list into append_sum()?


for sum in range(3):
lst = append_sum([1, 1, 2]) → why does this output [1, 2, 3, 5] instead of [1, 1, 2, 3, 5, 8]?


instead of


lst = [1, 1, 2]

for sum in range(3):
lst = append_sum(lst)

I don’t understand why it only works when the new lst is defined beforehand, even though it contains the same elements.

The problem here is what the loop is actually doing. The steps of the loop

def append_sum(lst)
   lst.append(lst[-1] + lst[-2])
   return lst

for sum in range(3):
   lst = append.sum([1, 1, 2])

are as follows:

  1. set sum = 0 as this is the first number in range(3)
  2. call append_sum([1, 1, 2]), which returns a value of [1, 1, 2, 3]
  3. set lst to this value, so lst = [1, 1, 2, 3]
  4. now back to the start, set sum = 1 as this is the next value in range(3)
  5. call append_sum([1, 1, 2]), which returns a value of [1, 1, 2, 3]
  6. set lst to this value, so lst = [1, 1, 2, 3]
  7. now back to the start again, with sum = 2 as this is the next (and last) value in range(3)
  8. call append_sum([1, 1, 2]), which returns a value of [1, 1, 2, 3]
  9. set lst to this value, so lst = [1, 1, 2, 3]
  10. loop ends as we have reached the end of range(3)

Hopefully this detailed breakdown of what the loop is doing demonstrates the issue. Just directly entering [1, 1, 2] into the function means that it will always call with this value, as this is a constant and not a variable. However, what we can do is replace this with a variable and this lets the list that is fed into the function change. So lets repeat the above steps but for my loop now:

lst = [1, 1, 2]

for sum in range(3):
    lst = append_sum(lst)
  1. set the value of lst to [1, 1, 2] initially.
  2. Entering the loop, we set sum = 0 as this is the first number in range(3)
  3. call append_sum(lst), with lst = [1, 1, 2] which returns a value of [1, 1, 2, 3]
  4. set lst to this value, so lst = [1, 1, 2, 3]
  5. now back to the start, set sum = 1 as this is the next value in range(3)
  6. call append_sum(lst), where now lst = [1, 1, 2, 3] which returns a value of [1, 1, 2, 3, 5]
  7. set lst to this value, so lst = [1, 1, 2, 3, 5]
  8. now back to the start again, with sum = 2 as this is the next (and last) value in range(3)
  9. call append_sum(lst), where now lst = [1, 1, 2, 3, 5] which returns a value of [1, 1, 2, 3, 5, 8]
  10. set lst to this value, so lst = [1, 1, 2, 3, 5, 8]
  11. loop ends as we have reached the end of range(3)

Here we can see the benefit of using a variable. Instead of repeatedly calling append_sum() with the same value, we are calling append_sum(lst), then overwriting that variable lst with it’s new value, and then repeating. Whereas in the previous version the input was the same every loop, in this version the input grows as the list grows, and so we get the correct output at the end.

Hopefully that breakdown helps you understand it a bit better! Questions are always welcome here.

1 Like

Ah I see! I was under the misconception that simply typing [1, 2, 3] as the argument would count as a list.
Thank you for clearing that up for me!

1 Like