Cleanest way to get last item from Python iterator

PythonPython 3.xPython 2.7Iterator

Python Problem Overview


What's the best way of getting the last item from an iterator in Python 2.6? For example, say

my_iter = iter(range(5))

What is the shortest-code / cleanest way of getting 4 from my_iter?

I could do this, but it doesn't seem very efficient:

[x for x in my_iter][-1]

Python Solutions


Solution 1 - Python

item = defaultvalue
for item in my_iter:
    pass

Solution 2 - Python

If you are using Python 3.x:

*_, last = iterator # for a better understanding check PEP 448
print(last)

if you are using python 2.7:

last = next(iterator)
for last in iterator:
    continue
print last


Side Note:

Usually, the solution presented above is what you need for regular cases, but if you are dealing with a big amount of data, it's more efficient to use a deque of size 1. (source)

from collections import deque

#aa is an interator
aa = iter('apple')

dd = deque(aa, maxlen=1)
last_element = dd.pop()

Solution 3 - Python

Use a deque of size 1.

from collections import deque

#aa is an interator
aa = iter('apple')

dd = deque(aa, maxlen=1)
last_element = dd.pop()

Solution 4 - Python

Probably worth using __reversed__ if it is available

if hasattr(my_iter,'__reversed__'):
    last = next(reversed(my_iter))
else:
    for last in my_iter:
        pass

Solution 5 - Python

As simple as:

max(enumerate(the_iter))[1]

Solution 6 - Python

This is unlikely to be faster than the empty for loop due to the lambda, but maybe it will give someone else an idea

reduce(lambda x,y:y,my_iter)

If the iter is empty, a TypeError is raised

Solution 7 - Python

There's this

list( the_iter )[-1]

If the length of the iteration is truly epic -- so long that materializing the list will exhaust memory -- then you really need to rethink the design.

Solution 8 - Python

I would use reversed, except that it only takes sequences instead of iterators, which seems rather arbitrary.

Any way you do it, you'll have to run through the entire iterator. At maximum efficiency, if you don't need the iterator ever again, you could just trash all the values:

for last in my_iter:
    pass
# last is now the last item

I think this is a sub-optimal solution, though.

Solution 9 - Python

The toolz library provides a nice solution:

from toolz.itertoolz import last
last(values)

But adding a non-core dependency might not be worth it for using it only in this case.

Solution 10 - Python

See this code for something similar:

http://excamera.com/sphinx/article-islast.html

you might use it to pick up the last item with:

[(last, e) for (last, e) in islast(the_iter) if last]

Solution 11 - Python

I would just use next(reversed(myiter))

Solution 12 - Python

The question is about getting the last element of an iterator, but if your iterator is created by applying conditions to a sequence, then reversed can be used to find the "first" of a reversed sequence, only looking at the needed elements, by applying reverse to the sequence itself.

A contrived example,

>>> seq = list(range(10))
>>> last_even = next(_ for _ in reversed(seq) if _ % 2 == 0)
>>> last_even
8

Solution 13 - Python

Alternatively for infinite iterators you can use:

from itertools import islice 
last = list(islice(iterator(), 1000))[-1] # where 1000 is number of samples 

I thought it would be slower then deque but it's as fast and it's actually faster then for loop method ( somehow )

Solution 14 - Python

The question is wrong and can only lead to an answer that is complicated and inefficient. To get an iterator, you of course start out from something that is iterable, which will in most cases offer a more direct way of accessing the last element.

Once you create an iterator from an iterable you are stuck in going through the elements, because that is the only thing an iterable provides.

So, the most efficient and clear way is not to create the iterator in the first place but to use the native access methods of the iterable.

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
QuestionPeterView Question on Stackoverflow
Solution 1 - PythonThomas WoutersView Answer on Stackoverflow
Solution 2 - PythonDhiaView Answer on Stackoverflow
Solution 3 - Pythonmartin23487234View Answer on Stackoverflow
Solution 4 - PythonJohn La RooyView Answer on Stackoverflow
Solution 5 - PythonChema CortesView Answer on Stackoverflow
Solution 6 - PythonJohn La RooyView Answer on Stackoverflow
Solution 7 - PythonS.LottView Answer on Stackoverflow
Solution 8 - PythonChris LutzView Answer on Stackoverflow
Solution 9 - PythonlumbricView Answer on Stackoverflow
Solution 10 - PythonJames BowmanView Answer on Stackoverflow
Solution 11 - Pythonthomas.macView Answer on Stackoverflow
Solution 12 - PythonWyrmwoodView Answer on Stackoverflow
Solution 13 - PythonqocuView Answer on Stackoverflow
Solution 14 - PythonludwigView Answer on Stackoverflow