我想知道对 for 循环中的最后一个元素进行特殊处理的最佳方式(更紧凑和“pythonic”方式)。有一段代码应该只在在元素之间调用,在最后一个被禁止。
这是我目前的做法:
for i, data in enumerate(data_list):
code_that_is_done_for_every_element
if i != len(data_list) - 1:
code_that_is_done_between_elements
有没有更好的办法?
注意:我不想通过诸如使用 reduce
之类的技巧来实现它。 ;)
最佳答案
在大多数情况下,将 第一次 迭代作为特例而不是最后一次迭代更容易(也更便宜):
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
https://stackoverflow.com/questions/1630320/