Question

I'm trying to perform checks on the first and last elements of an interator. It has several thousand entries, so I need an expeditious method of checking. If found this post, that put me onto this strategy.

first = True
for value in iterator:
   if first:
      do_stuff_to_first_iter
      first = False
   else:
      pass
do_stuff_to_last_iter

Anyone have any opinions on a quicker method of accomplishing this? Thanks a lot!

Was it helpful?

Solution

Get the first value with the next() function:

first = last = next(iterable, defaultvalue)
for last in iterable:
    pass

This assumes the iterable is finite.

For an empty iterable, first and last are set to defaultvalue. For an iterable with just one element, first and last will both refer to that one element. For any other finite iterable, first will have the first element, last the very last.

OTHER TIPS

Based on my answer to the linked question:

Probably worth using __reversed__ if it is available. If you are providing the iterator, and there is a sensible way to implement __reversed__ (ie without iterating from end to end) you should do it

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

According to my tests, islice is up to 3 times faster than for: pass or deque. This would require you to know how many items there will be, though.

last = next(islice(iterable, length - 1, length))

Or if you don't know the full length, but do know that it must be at least n, you could still "skip" to n as a shortcut:

rest = islice(iterable, n, None)
last = next(rest)
for last in rest:
    pass

You can use a deque with a maxlen of 1 to quickly get the last element of a finite iterator:

>>> from collections import deque
>>> last_getter = deque(maxlen=1)
>>> seq = range(10000)
>>> iseq = iter(seq)
>>>
>>> first = last = next(iseq, None)
>>> last_getter.extend(iseq)
>>> if last_getter: last = last_getter[0]
...
>>> print (first, last)
0 9999
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top