Posts: 4,653
Threads: 1,496
Joined: Sep 2016
Jul-04-2021, 07:58 PM
(This post was last modified: Jul-04-2021, 07:58 PM by Skaperen.)
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.
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Posts: 2,168
Threads: 35
Joined: Sep 2016
Jul-04-2021, 08:42 PM
(This post was last modified: Jul-04-2021, 08:42 PM by Yoriz.)
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
Posts: 1,358
Threads: 2
Joined: May 2019
How about iterating over the list backwards, that way it is the first item you want to treat differently.
Posts: 4,653
Threads: 1,496
Joined: Sep 2016
Jul-05-2021, 12:34 AM
(This post was last modified: Jul-05-2021, 12:34 AM by Skaperen.)
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.
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Posts: 1,950
Threads: 8
Joined: Jun 2018
Last item will always be there after iteration:
>>> for i in range(2):
... pass
...
>>> i
1
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Posts: 4,653
Threads: 1,496
Joined: Sep 2016
(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).
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Posts: 4,802
Threads: 77
Joined: Jan 2018
Jul-07-2021, 06:24 AM
(This post was last modified: Jul-07-2021, 06:24 AM by Gribouillis.)
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
>>>
Posts: 1,950
Threads: 8
Joined: Jun 2018
(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 :-)
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Posts: 582
Threads: 1
Joined: Aug 2019
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
Posts: 4,653
Threads: 1,496
Joined: Sep 2016
Jul-09-2021, 12:40 AM
(This post was last modified: Jul-09-2021, 12:41 AM by Skaperen.)
(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).
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
|