小编典典

检测“for”循环中最后一个元素的pythonic方法是什么?

all

我想知道对 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.;)


阅读 117

收藏
2022-05-16

共1个答案

小编典典

大多数时候,使第 一次 迭代成为特殊情况而不是最后一次迭代更容易(也更便宜):

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
2022-05-16