Detect If Item is the Last in a List
Rather than try and detect if you are at the last item, print the comma and newline when printing the next (which only requires detecting if you are at the first):
a = ['hello', 9, 3.14, 9]
for i, item in enumerate(a):
if i: # print a separator if this isn't the first element
print(',')
print(item, end='')
print() # last newline
The enumerate()
function adds a counter to each element (see What does enumerate mean?), and if i:
is true for all values of the counter except 0
(the first element).
Or use print()
to insert separators:
print(*a, sep=',\n')
The sep
value is inserted between each argument (*a
applies all values in a
as separate arguments, see What does ** (double star) and * (star) do for parameters?). This is more efficient than using print(',n'.join(map(str, a)))
as this doesn't need to build a whole new string object first.
While these answers may work for the specific case of the OP, I found they weren't suitable for broader application.
Here are the methods I could think of/saw here and their respective timings.
Index Method
urlist_len = len(urlist)-1
for x in urlist:
if urlist.index(x) == urlist_len:
pass
Negative Slice Method
for x in urlist:
if x == urlist[-1]:
pass
Enumerate Method
urlist_len = len(urlist)-1
for index, x in enumerate(urlist):
if index == urlist_len:
pass
Here are some timing for some different methods:
╔════════════════════════════════════════════════════════════════╗
║ Timing Results (s) ║
╠═══════════════════════╦════╦═════════╦════════╦═══════╦════════╣
║ List size ║ 20 ║ 200 ║ 2000 ║ 20000 ║ 200000 ║
╠═══════════════════════╬════╬═════════╬════════╬═══════╬════════╣
║ ║ 0 ║ 0.0006 ║ 0.051 ║ 5.2 ║ 560 ║
║ Index Method ║ ║ ║ ║ ║ ║
╠═══════════════════════╬════╬═════════╬════════╬═══════╬════════╣
║ ║ 0 ║ 0 ║ 0.0002 ║ 0.003 ║ 0.034 ║
║ Negative Slice Method ║ ║ ║ ║ ║ ║
╠═══════════════════════╬════╬═════════╬════════╬═══════╬════════╣
║ Enumerate Method ║ 0 ║ 0.00004 ║ 0.0005 ║ 0.016 ║ 0.137 ║
╚═══════════════════════╩════╩═════════╩════════╩═══════╩════════╝
Note: values <10us rounded to 0
As you can see, the index method is always slower, and it gets worse linearly with the list size. I don't see any reason to use it ever.
The Negative slice method is the fastest in all cases, but if you have duplicate items in your list, it will give you a false positive. Also, the negative slice method requires that the sequence you are iterating over supports indexing. So, in the case of duplicate items in your list (or not index supporting sequence) use the fast-but-not-fastest enumerate method.
Edit: as a commentator noted, calculating the length of the list within the loop isn't ideal. I was able to shave 35% off the enumerate method (not reflected in the table at this moment) using this knowledge.
tldr: use negative slice if all elements are unique objects and sequence supports indexing, otherwise enumerate method