Python Forum
checking for last item in for loop - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: checking for last item in for loop (/thread-34179.html)

Pages: 1 2


checking for last item in for loop - Skaperen - Jul-04-2021

i am iterating over a list and need to do something slightly different for the last item in the list. i currently do this with a counter that is 1 on the first cycle and compare it to the len() of the list. i am wondering if there is a cleaner way to do this.


RE: checking for last item in for loop - Yoriz - Jul-04-2021

Here one way of doing it which returns a tuple of bool, item, the bool is True if its the last item.
items = range(3)

def iter_is_last(items):
    iterable = iter(items)
    previous = next(iterable)
    for last in iterable:
        yield False, previous
        previous = last
    yield True, last

for is_last, item in iter_is_last(items):
    if is_last:
        print(f'Last item is {item}')
    else:
        print(f'Item is {item}')
Output:
Item is 0 Item is 1 Last item is 2



RE: checking for last item in for loop - jefsummers - Jul-04-2021

How about iterating over the list backwards, that way it is the first item you want to treat differently.


RE: checking for last item in for loop - Skaperen - Jul-05-2021

gotta run it forward. the loop does a series of compression.open calls using the open file object from the previous call as the "file" to be opened. each call must be binary except the last will be whatever was really needed. most times there is only one layer of compression. but sometimes there are more. the list being iterated is a list of compression modules to use for which algorithm that layer is going to use. a previous messy version works. this is to be a cleaner version that i will release under MIT license.


RE: checking for last item in for loop - perfringo - Jul-05-2021

Last item will always be there after iteration:

>>> for i in range(2):
...     pass
...
>>> i
1



RE: checking for last item in for loop - Skaperen - Jul-07-2021

(Jul-05-2021, 05:41 AM)perfringo Wrote: Last item will always be there after iteration:

>>> for i in range(2):
...     pass
...
>>> i
1

i am doing an lzma.open() or bzip2.open() or gzip.open() call each time. the mode needs to be binary each time except the last. are you assuming that i need to do an additional action after the last? i need to change the 2nd argument on the last one (even if it is the only one).


RE: checking for last item in for loop - Gribouillis - Jul-07-2021

You could use itertools
>>> import itertools as itt
>>> L = list('ulivohta')
>>> imode = itt.chain(itt.repeat('rb', len(L)-1), ('r',))
>>> 
>>> for item, mode in zip(L, imode):
...     print(item, mode)
... 
u rb
l rb
i rb
v rb
o rb
h rb
t rb
a r
>>> 



RE: checking for last item in for loop - perfringo - Jul-07-2021

(Jul-07-2021, 12:19 AM)Skaperen Wrote: are you assuming that i need to do an additional action after the last? i need to change the 2nd argument on the last one (even if it is the only one).

As no code provided then it is hard to do anything else but assume. The idea was just very simple beginner level approach:

>>> list_ = []
>>> for i in range(4):
...     list_.append(i**2)   # do something with every item
... else:                    # no-break
...     list_[-1] = i        # redo last one with something else
...
>>> list_
[0, 1, 4, 3]
If operations are not expensive, why not :-)


RE: checking for last item in for loop - ibreeden - Jul-07-2021

I find this the most elegant way to process the list:
the_list = [1,2,3,4]

for i in the_list[0:-1]:
    print(f"Processing {i}")

print(f"Post processing {the_list[-1]}")
Output:
Processing 1 Processing 2 Processing 3 Post processing 4



RE: checking for last item in for loop - Skaperen - Jul-09-2021

(Jul-07-2021, 10:58 AM)ibreeden Wrote: I find this the most elegant way to process the list:
the_list = [1,2,3,4]

for i in the_list[0:-1]:
    print(f"Processing {i}")

print(f"Post processing {the_list[-1]}")
Output:
Processing 1 Processing 2 Processing 3 Post processing 4

for cases where the entire body of the loop changes, i agree that is the best way. but if the last cycle needs to change only a portion, more so the smaller that portion is, i would prefer to avoid any duplicated code and have every cycle performed by the same body code that tests for the case of the last cycle. if the common part of that code ever needs to be changed or trapped for debugging, avoiding duplication makes code maintenance easier (so there is never an issue of what needs to be the same actually being the same).