Remove the last N elements of a list

PythonList

Python Problem Overview


Is there a a better way to remove the last N elements of a list.

for i in range(0,n):
    lst.pop( )

Python Solutions


Solution 1 - Python

Works for n >= 1

>>> L = [1,2,3, 4, 5]
>>> n=2
>>> del L[-n:]
>>> L
[1, 2, 3]

Solution 2 - Python

if you wish to remove the last n elements, in other words, keep first len - n elements:

lst = lst[:len(lst)-n]

Note: This is not an in memory operation. It would create a shallow copy.

Solution 3 - Python

As Vincenzooo correctly says, the pythonic lst[:-n] does not work when n==0.

The following works for all n>=0:

lst = lst[:-n or None]

I like this solution because it is kind of readable in English too: "return a slice omitting the last n elements or none (if none needs to be omitted)".

This solution works because of the following:

  • x or y evaluates to x when x is logically true (e.g., when it is not 0, "", False, None, ...) and to y otherwise. So -n or None is -n when n!=0 and None when n==0.
  • When slicing, None is equivalent to omitting the value, so lst[:None] is the same as lst[:] (see here).

As noted by @swK, this solution creates a new list (but immediately discards the old one unless it's referenced elsewhere) rather than editing the original one. This is often not a problem in terms of performance as creating a new list in one go is often faster than removing one element at the time (unless n<<len(lst)). It is also often not a problem in terms of space as usually the members of the list take more space than the list itself (unless it's a list of small objects like bytes or the list has many duplicated entries). Please also note that this solution is not exactly equivalent to the OP's: if the original list is referenced by other variables, this solution will not modify (shorten) the other copies unlike in the OP's code.

A possible solution (in the same style as my original one) that works for n>=0 but: a) does not create a copy of the list; and b) also affects other references to the same list, could be the following:

    lst[-n:n and None] = []

This is definitely not readable and should not be used. Actually, even my original solution requires too much understanding of the language to be quickly read and univocally understood by everyone. I wouldn't use either in any real code and I think the best solution is that by @wonder.mice: a[len(a)-n:] = [].

Solution 4 - Python

Just try to del it like this.

del list[-n:]

Solution 5 - Python

I see this was asked a long ago, but none of the answers did it for me; what if we want to get a list without the last N elements, but keep the original one: you just do list[:-n]. If you need to handle cases where n may equal 0, you do list[:-n or None].

>>> a = [1,2,3,4,5,6,7]
>>> b = a[:-4]
>>> b
[1, 2, 3]
>>> a
[1, 1, 2, 3, 4, 5, 7]

As simple as that.

Solution 6 - Python

Should be using this:

a[len(a)-n:] = []

or this:

del a[len(a)-n:]

It's much faster, since it really removes items from existing array. The opposite (a = a[:len(a)-1]) creates new list object and less efficient.

>>> timeit.timeit("a = a[:len(a)-1]\na.append(1)", setup="a=range(100)", number=10000000)
6.833014965057373
>>> timeit.timeit("a[len(a)-1:] = []\na.append(1)", setup="a=range(100)", number=10000000)
2.0737061500549316
>>> timeit.timeit("a[-1:] = []\na.append(1)", setup="a=range(100)", number=10000000)
1.507638931274414
>>> timeit.timeit("del a[-1:]\na.append(1)", setup="a=range(100)", number=10000000)
1.2029790878295898

If 0 < n you can use a[-n:] = [] or del a[-n:] which is even faster.

Solution 7 - Python

This is one of the cases in which being pythonic doesn't work for me and can give hidden bugs or mess. None of the solutions above works for the case n=0. Using l[:len(l)-n] works in the general case:

l=range(4)
for n in [2,1,0]: #test values for numbers of points to cut
    print n,l[:len(l)-n]

This is useful for example inside a function to trim edges of a vector, where you want to leave the possibility not to cut anything.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTheoView Question on Stackoverflow
Solution 1 - PythonjamylakView Answer on Stackoverflow
Solution 2 - PythonkarthikrView Answer on Stackoverflow
Solution 3 - PythonLuca CitiView Answer on Stackoverflow
Solution 4 - PythonYarkeeView Answer on Stackoverflow
Solution 5 - Pythonchamini2View Answer on Stackoverflow
Solution 6 - Pythonwonder.miceView Answer on Stackoverflow
Solution 7 - PythonVincenzoooView Answer on Stackoverflow