55

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 
1
  • 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. Commented Jul 22, 2019 at 1:01

7 Answers 7

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)
Sign up to request clarification or add additional context in comments.

7 Comments

I advise you against using list and iter as variable names as they shadow the builtins
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.
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))
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: 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.
|
42

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])

1 Comment

+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.
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

1 Comment

For the first option: With Python 3 izip became the built-in zip so use that instead.
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.

Comments

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

Comments

-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

1 Comment

This is slow and doesn't work if the list has duplicates.
-4
for i in items:
  if i == items[-1]:
    print 'The last item is: '+i

3 Comments

This doesn't work when different elements are same like in items = [1,2,1]
Isn't this expensive?
It works when the elements are in the list multiple times if you use a single variable

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.