当使用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

我如何简化或改进它?


当前回答

我喜欢@ethan-t的方法,但从我的角度来看,True是危险的。

data_list = [1, 2, 3, 2, 1]  # sample data
L = list(data_list)  # destroy L instead of data_list
while L:
    e = L.pop(0)
    if L:
        print(f'process element {e}')
    else:
        print(f'process last element {e}')
del L

这里,data_list的值是,最后一个元素的值等于列表的第一个元素。L可以与data_list交换,但在这种情况下,循环后它的结果为空。如果你在处理前检查该列表不为空或检查不需要(哎呀!),也可以使用True。

data_list = [1, 2, 3, 2, 1]
if data_list:
    while True:
        e = data_list.pop(0)
        if data_list:
            print(f'process element {e}')
        else:
            print(f'process last element {e}')
            break
else:
    print('list is empty')

好处是它很快。坏的-它是可销毁的(data_list变成空)。

最直观的解决方案:

data_list = [1, 2, 3, 2, 1]  # sample data
for i, e in enumerate(data_list):
    if i != len(data_list) - 1:
        print(f'process element {e}')
    else:
        print(f'process last element {e}')

哦,是的,你已经提出来了!

其他回答

迟到总比不到好。您的原始代码使用了enumerate(),但您只使用i索引来检查它是否是列表中的最后一项。下面是一个使用负索引的更简单的替代方法(如果你不需要enumerate()):

for data in data_list:
    code_that_is_done_for_every_element
    if data != data_list[-1]:
        code_that_is_done_between_elements

if data != data_list[-1]检查迭代中的当前项是否不是列表中的最后一项。

希望这能有所帮助,即使是在近11年后。

如果要循环List, 使用枚举函数是最好的尝试之一。

for index, element in enumerate(ListObj):
    # print(index, ListObj[index], len(ListObj) )

    if (index != len(ListObj)-1 ):
        # Do things to the element which is not the last one
    else:
        # Do things to the element which is the last one

如果你正在浏览这个列表,这对我来说也是有效的:

for j in range(0, len(Array)):
    if len(Array) - j > 1:
        notLast()

如果你乐意用这个清单来破坏,那么下面就是。 为了加快从O(n²)到O(n)的过程,我们将反转列表,因为pop(0)每次迭代都会移动列表——参见下面Nicholas Pipitone的评论

data_list.reverse()
while data_list:
   value = data_list.pop()
   code_that_is_done_for_every_element(value)
   if data_list:
       code_that_is_done_between_elements(value)
   else:
       code_that_is_done_for_last_element(value)


这适用于空列表和非唯一项的列表。 因为列表通常是暂时的,所以这种方法非常有效……以销毁列表为代价。

您可以在输入数据上使用滑动窗口来查看下一个值,并使用哨兵来检测最后一个值。这适用于任何可迭代对象,所以你不需要事先知道它的长度。成对实现来自itertools recipes。

from itertools import tee, izip, chain

def pairwise(seq):
    a,b = tee(seq)
    next(b, None)
    return izip(a,b)

def annotated_last(seq):
    """Returns an iterable of pairs of input item and a boolean that show if
    the current item is the last item in the sequence."""
    MISSING = object()
    for current_item, next_item in pairwise(chain(seq, [MISSING])):
        yield current_item, next_item is MISSING:

for item, is_last_item in annotated_last(data_list):
    if is_last_item:
        # current item is the last item