On Wed, Oct 28, 2015 at 02:48:05PM +0000, Flynn, Stephen (L & P - IT) wrote:
> I'm iterating through a list and I'd like to know when I'm at > the end of the said list, so I can do something different. For example > > list_of_things = ['some', 'special', 'things'] > for each_entry in list_of_things: > print(each_entry) > if each_entry == list_of_things[-1]: # do something special to > last entry > ...etc > > > Is this the idiomatic way to detect you're at the last entry in a list > as you iterate through it? But it doesn't detect the last entry. Consider: list_of_things = ["cheese", "fruit", "cheese", "fish", "cheese"] Your code will perform the special processing three times. There's no idiomatic way to do this because it is a fairly unusual thing to do. Normally we want to process all the items in a list the same way. But here are some solutions: (1) Avoid the problem altogether by arranging matters so that the "last item" isn't in the list at all. list_of_things = ['some', 'special'] last = 'things' for each_entry in list_of_things: print(each_entry) print(last.upper()) (2) Slicing. Requires a little extra memory, but is probably the closest to an idiomatic solution for this sort of thing. list_of_things = ['some', 'special', 'things'] for each_entry in list_of_things[:-1]: print(each_entry) print(list_of_things[-1].upper()) (3) Add a sentinel to the list. list_of_things = ['some', 'special', None, 'things'] for each_entry in list_of_things: if each_entry is None: break print(each_entry) print(list_of_things[-1].upper()) (4) Count the items. list_of_things = ['some', 'special', 'things'] for i, each_entry in enumerate(list_of_things): if i == len(list_of_things) - 1: # Watch out for off-by-one errors! each_entry = each_entry.upper() print(each_entry) (5) What if you're dealing with an iterable of unknown length that can't be sliced? The obvious answer is to convert to a list: list_of_things = list(things) but suppose you have some reason for not wanting to do that. (Perhaps things is truly huge, billions of items.) Something like this should help: prev = [] for this in things: if prev: print(prev[0]) prev = [this] print(prev[0].upper()) We can make this a little more efficient if things is an actual iterator: things = iter(things) try: prev = next(things) except StopIteration: # No things at all. pass else: for this in things: print(prev) prev = this print(prev.upper()) -- Steve _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor