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

新手上路,请多包涵

我想知道对 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 之类的技巧来实现它。 ;)

原文由 e.tadeu 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 557
2 个回答

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

 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

原文由 Ferdinand Beyer 发布,翻译遵循 CC BY-SA 3.0 许可协议

虽然这个问题很老了,但我通过谷歌来到这里,我发现了一个非常简单的方法:列表切片。假设您想在所有列表条目之间放置一个“&”。

 s = ""
l = [1, 2, 3]
for i in l[:-1]:
    s = s + str(i) + ' & '
s = s + str(l[-1])

这将返回“1 & 2 & 3”。

原文由 BeckmaR 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题