我想知道对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
有什么更好的办法吗?
注意:我不希望使用hack之类的东西reduce。;)
reduce
;)
在大多数情况下,使第 一个 迭代成为特殊情况而不是最后一个案例更容易(且更便宜):
first = True for data in data_list: if first: first = False else: between_items() item()
这将适用于任何迭代过程,即使对于那些没有迭代的对象也是如此len():
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“特殊情况”循环更好。
str.join()
for
使用相同的原理,但更紧凑:
for i, line in enumerate(data_list): if i > 0: between_items() item()
看起来很熟悉,不是吗?:)
对于@ofko以及其他确实需要确定iterable的当前值是否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