В большинстве случаев проще (и дешевле) сделать первую итерацию особой, а не последнюю:
first = True
for data in data_list:
if first:
first = False
else:
between_items()
item()
Это будет работать для любого повторяемого, даже для тех, которые не имеют len()
:
file = open('/path/to/file')
for line in file:
process_line(line)
# No way of telling if this is the last line!
Кроме того, я не думаю, что есть вообще превосходное решение, поскольку оно зависит от того, что вы пытаетесь сделать. Например, если вы строите строку из списка, естественно, ее лучше использовать, str.join()
чем использовать for
цикл «с особым случаем».
Используя тот же принцип, но более компактный:
for i, line in enumerate(data_list):
if i > 0:
between_items()
item()
Выглядит знакомо, не правда ли? :)
Для @ofko и других, которым действительно необходимо выяснить, является ли текущее значение итерируемого без len()
последнего, вам нужно смотреть в будущее:
def lookahead(iterable):
"""Pass through all values from the given iterable, augmented by the
information if there are more values to come after the current one
(True), or if it is the last value (False).
"""
# Get an iterator and pull the first value.
it = iter(iterable)
last = next(it)
# Run the iterator to exhaustion (starting from the second value).
for val in it:
# Report the *previous* value (more to come).
yield last, True
last = val
# Report the last value.
yield last, False
Тогда вы можете использовать это так:
>>> for i, has_more in lookahead(range(3)):
... print(i, has_more)
0 True
1 True
2 False