当使用for循环迭代时,我如何处理输入的最后一个元素?特别是,如果有代码应该只出现在元素之间(而不是在最后一个元素之后),我该如何构造代码?

目前,我写的代码是这样的:

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

我如何简化或改进它?


当前回答

有多种方法。切片是最快的。再添加一个使用.index()方法的:

>>> l1 = [1,5,2,3,5,1,7,43]                                                 
>>> [i for i in l1 if l1.index(i)+1==len(l1)]                               
[43]

其他回答

使用切片和is检查最后一个元素:

for data in data_list:
    <code_that_is_done_for_every_element>
    if not data is data_list[-1]:
        <code_that_is_done_between_elements>

买者自负:这只在列表中的所有元素实际上都不同的情况下才有效(在内存中有不同的位置)。实际上,Python可以检测相同的元素并为它们重用相同的对象。例如,对于具有相同值和普通整数的字符串。

“code between”是头尾模式的一个例子。

你有一个项目,后面是一系列(项目之间)对。您还可以将其视为(item, between)对的序列,后跟一个item。通常更简单的做法是将第一个元素作为特殊元素,而将所有其他元素作为“标准”情况。

此外,为了避免重复代码,必须提供一个函数或其他对象来包含不想重复的代码。在循环中嵌入if语句,除非有一次总是假的,这有点傻。

def item_processing( item ):
    # *the common processing*

head_tail_iter = iter( someSequence )
head = next(head_tail_iter)
item_processing( head )
for item in head_tail_iter:
    # *the between processing*
    item_processing( item )

这更可靠,因为它更容易证明,它不会创建额外的数据结构(即列表的副本),也不需要大量浪费if条件的执行,if条件总是假的,只有一次例外。

谷歌让我想到了这个老问题,我想我可以用不同的方法来解决这个问题。

这里的大多数答案将处理一个正确的处理for循环控件,但如果data_list是可销毁的,我建议你从列表中弹出项目,直到你得到一个空列表:

while True:
    element = element_list.pop(0)
    do_this_for_all_elements()
    if not element:
        do_this_only_for_last_element()
        break
    do_this_for_all_elements_but_last()

如果不需要对最后一个元素做任何操作,甚至可以使用while len(element_list)。我发现这个解决方案比处理next()更优雅。

我发现在循环表达式之前定义循环值很方便。对于这个方框示例,匹配循环中的值,或者其他可能需要它的地方。

numberofboxes = 1411

for j in range(1,numberofboxes):
    if j != numberofboxes - 1:
        print ("},")
    else:
        print("}")

将最后一项的特殊处理延迟到循环之后。

>>> for i in (1, 2, 3):
...     pass
...
>>> i
3