How can we select the last few elements of a list?

Question

In the context of this code challenge, how can we select the last few elements of a list?

Answer

There are several ways that you can select the last few elements of a list. Some of these are as follows:

# Given this list
numbers = [1, 2, 3, 4, 5]
# we are trying to obtain the last two elements
[4, 5]

# Create a new list filled with the elements by index
[numbers[-2], numbers[-1]]

# Obtain the range of elements for a positive start and end index
numbers[len(numbers)-2:len(numbers)]

# Obtain the list slice using a negative start index.
numbers[-2:len(numbers)]

# Without needing to specify the end index, we can do
numbers[len(numbers)-2:]
numbers[-2:]
8 Likes

What exactly happens when we slice with a negative start index followed by len(numbers)?
For example:
list=[1, 1, 2, 3, 5, 8]
print(list[-4:3])
print(list[-4:1])

when i execute this piece of code ,my respective outputs are;
[2]
[ ]

I don’t quite understand what exactly happened??

1 Like
list element           1      1     2     3     5     8
index                  0      1     2     3     4     5  
negative index        -6     -5    -4    -3    -2    -1  

The rule is the same as with positive indices: return a list beginning with the element at the first index, and ending with the element at the final index less 1.

In your first example, list[-4 : 3] , that rule includes only the element, 2, since list[-4] is 2 and list[final index (3) less 1] is list[2], also the same element, 2. In your second case, the second element is before the first, which always returns an empyt list.

3 Likes

Specifically for this exercise… can someone tell me why this does not work?

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

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

last_two_added is defined in the first line as a fixed value (in this case, 1 + 2, or 3). It retains that value throughout the function.

To make it work as you want, you need to make last_two_added a function:

def last_two_added(lst):
    return lst[-2] + lst[-1]

def append_sum(lst):  
  lst.append(last_two_added(lst))
  lst.append(last_two_added(lst))
  lst.append(last_two_added(lst))
  return lst

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

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

BTW, you do not need return. Omit the return statement and call it like this:

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

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

5 Likes

Extra Study

Let’s not forget negative indices, which can be useful in this instance…

>>> a = list('abcdefghijklmnopqrstuvwxyz')
>>> a[-2:]
['y', 'z']
>>> 

Given a list of numbers, we can extend it for this exercise using the in-built sum() function…

>>> def last_two_added(a = [1, 1]):
    '''
    a = supplied list of values or default
    '''
    a += [sum(a[-2:])]
    return a

>>> last_two_added()
[1, 1, 2]
>>> last_two_added()
[1, 1, 2, 3]
>>> last_two_added()
[1, 1, 2, 3, 5]
>>> last_two_added()
[1, 1, 2, 3, 5, 8]
>>> 

While this may not be completely practical, as it uses the sum function that may not yet be familiar, as may negative indices, slices and default parameters, it does what the exercise expects.

What the performance difference between sum and append is, I couldn’t say. It’s just a new take on the same problem.

8 Likes

thanks patrick! you’re a genius!

1 Like

Hi. Thanks Patrick, but I tried to omit the return lst and instead use print, and it returned “none”. Can you help.

lst = [1, 1, 2]
def last_two_added(lst):
return lst[-2] + lst[-1]

def append_sum(lst):
lst.append(last_two_added(lst))
lst.append(last_two_added(lst))
lst.append(last_two_added(lst))
print(lst)

You never call the function append_sum()

Please use the code formatter, accessed via the </> icon near the middle of the menu bar that appears at the top of the text box when you are typing in it.

Is this what you meant?

lst = [1, 1, 2]
def last_two_added(lst):
    return lst[-2] + lst[-1]

def append_sum(lst):
    lst.append(last_two_added(lst))
    lst.append(last_two_added(lst))
    lst.append(last_two_added(lst))
print(lst)

If so, you need append_sum(lst) before the print() statement.

lst = [1, 1, 2]
def last_two_added(lst):
  return lst[-2] + lst[-1]

def append_sum(lst):
  lst.append(last_two_added(lst))
  lst.append(last_two_added(lst))
  lst.append(last_two_added(lst))
  print(lst)

Yes. I see that I never called it. Thank you. 
This is what I  had. If I call the append_sum () and the print(lst) outside of the function it works.  

MaryJ
1 Like

Is there a way to loop this? I tired this but not sure what I am doing wrong.

def append_sum(lst):
  i = 0
  while i < 4:
    lst.append(lst[-1] + lst[-2])
    i +=1
    return lst

#Uncomment the line below when your function is done
print(append_sum([1, 1, 2]))

As soon as return is reached one time, the function halts.
Move return out so it is at the same level as while.

1 Like

I did mine almost the same as yours. The only difference is, instead of a manual counter, I decided to use the length of the list + 3 for the end of my loop so I could apply it to different sized lists instead of the one that would be run from the commented example line.

def append_sum(lst):
  top = len(lst) + 3
  while len(lst) < top:
    lst.append(lst[-1]+lst[-2])
  return lst

It works fine, and like the other user mentioned, double check your indentations so the return occurs after the while loop has completed.Preformatted text

2 Likes

I’m glad I can compare code in this forum. Gives me a better idea how to write better in the future

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



Now to get into the D. R. Y. part of coding to really streamline that code…

1 Like

This is how I solved the problem. I added the last two indexes within the .append and ran it 3 times within the function.

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

Now, is there a way you can get that to happen without writing the same line three times?

2 Likes

Hi Patrick,

Can we use a loop in the append_sum() function instead of repeating three times?

Certainly! That is a much more general approach, and as such, more “Pythonic.”

Amazing solution but could you please explain working what exactly happing here with single move ?