54

I need to do some special operation for the last element in a list. Is there any better way than this?

array = [1,2,3,4,5] 
for i, val in enumerate(array): 
  if (i+1) == len(array): 
    // Process for the last element 
  else: 
    // Process for the other element 
prosseek
  • 182,215
  • 215
  • 566
  • 871
  • 1
    @PaulKenjora He's already using `enumerate` to do pretty much the same thing in the link you gave. He's asking for a _better and more pythonic way_ to detect the last element, rather than using the approach he listed. Should not be considered a duplicate. – Kobato Jul 22 '19 at 01:01

7 Answers7

68
for item in list[:-1]:
    print "Not last: ", item
print "Last: ", list[-1]

If you don't want to make a copy of list, you can make a simple generator:

# itr is short for "iterable" and can be any sequence, iterator, or generator

def notlast(itr):
    itr = iter(itr)  # ensure we have an iterator
    prev = itr.next()
    for item in itr:
        yield prev
        prev = item

# lst is short for "list" and does not shadow the built-in list()
# 'L' is also commonly used for a random list name
lst = range(4)
for x in notlast(lst):
    print "Not last: ", x
print "Last: ", lst[-1]

Another definition for notlast:

import itertools
notlast = lambda lst:itertools.islice(lst, 0, len(lst)-1)
Darius Bacon
  • 14,921
  • 5
  • 53
  • 53
liori
  • 40,917
  • 13
  • 78
  • 105
  • 4
    I advise you against using `list` and `iter` as variable names as they shadow the builtins – John La Rooy Mar 12 '10 at 01:15
  • I gave you +1, but the code you had there for the iterator case didn't work. I'm going to go in and fix it now. – steveha Mar 12 '10 at 01:56
  • A simpler version of your first definition of notlast: def butlast(xs): prev = xs.next() for x in xs: yield prev prev = x (I'd also add a first line: xs = iter(xs)) – Darius Bacon Mar 12 '10 at 02:11
  • Following steveha's example, I went ahead and edited my suggestion in. I'm not sure that was really the polite thing to do -- hope you don't mind. – Darius Bacon Mar 12 '10 at 04:13
  • @Darius: I'm glad you did it. I don't sit on SO 24h/day, and if OP gets best answer possible, that's good thing. – liori Mar 12 '10 at 11:15
  • This is way too complicated, pythonic is about readable as much as anything else. Hence the Python gods invented enumerate. The better answer ( using enumerate ) to this exact question is in another Stack Overflow thread at: http://stackoverflow.com/questions/4751092/identify-which-iteration-you-are-on-in-a-loop-in-python – Paul Kenjora Jan 09 '16 at 19:41
  • Why do people always try to find the most complicated solution for any simple problem? The questioner's example is one the best solutions, with the other one being comparing to the last element with `is`. – Bachsau Aug 22 '19 at 15:41
41

If your sequence isn't terribly long then you can just slice it:

for val in array[:-1]:
  do_something(val)
else:
  do_something_else(array[-1])
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 9
    +1 for "for/else", but note that if the "do something" code actually involves a break statement (early termination of the loop) then the else code would be skipped. Whether that's relevant in this case is up to the OP, but it should be noted. – Peter Hansen Mar 12 '10 at 00:26
9

using itertools

>>> from itertools import repeat, chain,izip
>>> for val,special in izip(array, chain(repeat(False,len(array)-1),[True])):
...     print val, special
... 
1 False
2 False
3 False
4 False
5 True

Version of liori's answer to work on any iterable (doesn't require len() or slicing)

def last_flagged(seq):
    seq = iter(seq)
    a = next(seq)
    for b in seq:
        yield a, False
        a = b
    yield a, True        

mylist = [1,2,3,4,5]
for item,is_last in last_flagged(mylist):
    if is_last:
        print "Last: ", item
    else:
        print "Not last: ", item
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
0

If your logic is never breaking out of the loop then a for...else construct might work:

In [1]: count = 0
   ...: for i in [1, 2, 3]:
   ...:     count +=1
   ...:     print("any item:", i)
   ...: else:
   ...:     if count:
   ...:         print("last item: ", i)
   ...:
any item: 1
any item: 2
any item: 3
last item:  3

You need the count variable just in case the iterable is empty, otherwise the variable i won't be defined.

Pedro M Duarte
  • 26,823
  • 7
  • 44
  • 43
0

Use more_itertools:

import more_itertools

array = [1,2,3,4,5]
peekable = more_itertools.peekable(array)
last = object()
for val in peekable:
    if peekable.peek(last) is last: 
        print('last', val)
    else: 
        print(val)

Gives:

1
2
3
4
last 5
Isaac To
  • 131
  • 1
  • 5
-3

Simple way with an if condition:

for item in list:
    print "Not last: ", item
    if list.index(item) == len(list)-1:
        print "Last: ", item
Max Dy
  • 307
  • 3
  • 7
-4
for i in items:
  if i == items[-1]:
    print 'The last item is: '+i
GreenAsJade
  • 14,459
  • 11
  • 63
  • 98
ahmad88me
  • 3
  • 1