Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

All but the last N elements of iterator in Python

What is the best way to get all but the last N elements of an iterator in Python? Here is an example of it in theoretical action:

>>> list(all_but_the_last_n(range(10), 0))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(all_but_the_last_n(range(10), 2))
[0, 1, 2, 3, 4, 5, 6, 7]
like image 944
Zach Dwiel Avatar asked Jul 09 '11 02:07

Zach Dwiel


People also ask

How do I get the last 10 elements of a list in Python?

Method #2 : Using islice() + reversed() The inbuilt functions can also be used to perform this particular task. The islice function can be used to get the sliced list and reversed function is used to get the elements from rear end.

How do you traverse the last element of a list in Python?

Get the last element of the list using the “length of list - 1” as an index and print the resultant last element of the list. Get the last element of the list using − 1(negative indexing) as the index and print the resultant last element of the list.

How do I get the last two items in a list Python?

Any element in list can be accessed using zero based index. If index is a negative number, count of index starts from end. As we want second to last element in list, use -2 as index.


3 Answers

Just for the fun of it, here's a variation on Ignacio's solution that doesn't require a deque.

>>> def truncate(it, n):
...     cache = [next(it) for i in range(n)]
...     index = 0
...     for val in it:
...         val, cache[index] = cache[index], val
...         index = (index + 1) % n
...         yield val

I wasn't especially concerned with speed when I wrote the above... but perhaps this would be a tad faster:

def truncate(it, n):
    cache = [next(it) for i in range(n)]
    index = 0
    for val in it:
        yield cache[index]
        cache[index] = val
        index = (index + 1) % n
like image 148
senderle Avatar answered Sep 28 '22 14:09

senderle


Use a collections.deque. Push N items from the source on the first invocation. On each subsequent invocation, pop an item out, push an item in from the source, and yield the popped item.

like image 25
Ignacio Vazquez-Abrams Avatar answered Sep 28 '22 15:09

Ignacio Vazquez-Abrams


Based on Ignacio Vazquez-Abrams's description:

from collections import deque

def all_but_the_last_n(iterable, count):
    q = deque()
    i = iter(iterable)
    for n in range(count):
        q.append(i.next())
    for item in i:
        q.append(item)
        yield q.popleft()

I wondered whether it was better to use the deque right to left (append, popleft) or left to right (appendleft, pop). So i timed it with python 2.5.2 and found that rtl was 3.59 usec while ltr was 3.53 usec. The difference of 0.06 usec is not significant. the test was to append a single item and pop a single item.

like image 38
Dan D. Avatar answered Sep 28 '22 15:09

Dan D.