遍历Python列表并对最后一个元素执行某些操作

遍历Python列表并对最后一个元素执行某些操作,python,Python,我正在寻找一种pythonic方法来迭代列表,并在最后一个(并且仅在最后一个)元素上执行某些操作。有两种方法可以做到这一点,我想第二种是最好的: for item in a_list: #do something to every element if a_list.index(item) == len(a_list) - 1: # do something to the last one 及 但是,我想知道是否有一种方法可以不在我已经迭代过的列表上调用len(

我正在寻找一种pythonic方法来迭代列表,并在最后一个(并且仅在最后一个)元素上执行某些操作。有两种方法可以做到这一点,我想第二种是最好的:

for item in a_list:
    #do something to every element
    if a_list.index(item) == len(a_list) - 1:
        # do something to the last one

但是,我想知道是否有一种方法可以不在我已经迭代过的列表上调用
len()
。顺便说一句,我很高兴被告知这不是我应该担心的事情

您可以使用:

a_list[-1]

要访问最后一个元素,您正在制造问题:)您的方法确实没有任何问题

如果要循环,可以找到长度。然后访问最后一件事。或者只做循环,然后用
列表[-1]
做一些事情。别出心裁的方法,用
搜索其他的
——你可以用谷歌搜索。但话说回来,您的代码确实没有问题。

您可以使用:

如您所见,对列表中的每个元素都执行一个操作,但最后一个元素会执行一个额外的操作

还要注意,
else
块只有在循环正常退出且未遇到
break
语句时才会运行。这种行为似乎是正确的,因为如果遇到
break
语句,那么循环将显式退出,我们就完成了列表

for item in lst:
   do_something_to(item)
else:
   do_something_extra_special_to_last(item)
在这里,我只是假设您想对最后一项做一些额外的事情(正常的操作仍然会事先进行)。我还假设您没有点击任何
break
语句(在这种情况下,
else
将不会执行)。当然,您并不真正需要
其他

for item in lst:
    do_something_to(item)
do_something_extra_special_to_last(item)
由于循环变量“泄漏”到封闭范围内,因此也应该工作,如果存在您担心的中断,并且您确实在序列上循环,为什么不:

for item in lst:
   do_something_to(item)
do_something_extra_special_to_last(lst[-1])

我当然更喜欢你现在的两个版本的第二个版本<如果列表中存在重复项,并且每次迭代都执行
O(n)
操作,而
len
O(1)
,则code>index
可能会导致问题

但是,一般来说,由于您希望对最后一项做一些额外的(没有不同的)操作,我只想在
for
循环之后将其作为一个单独的步骤:

for item in lst:
    # do something to every element
# do something to lst[-1]
即使出现
中断
(与使用
else
)也会起作用,并影响列表中的最后一项,而不是重复的最后一项-这可能是或可能不是期望的行为。

请考虑:

li[:]=[do_somthing(item) for item in li]  # something to every item in place
li[-1]=something_extra(li[-1])            # additional to last item
vs

如果您对这些进行计时,您可以看到这是最快的方式:

def do_something(e):
    return e*2

def something_extra(e):
    return e/2

def f1(li):
    for i, item in enumerate(li):
        li[i]=do_something(item)
        if i==len(li)-1:
            li[i]=something_extra(item)

def f2(li):
    li[:]=[do_something(item) for item in li]
    li[-1]=something_extra(li[-1])

def f3(li):
    for i, item in enumerate(li):
        li[i]=do_something(item)
    li[i]=something_extra(item)

if __name__ == '__main__':
    import timeit
    for f in (f1,f2,f3):
        t=timeit.timeit("f(range(1000))", 
                         setup="from __main__ import f,do_something,something_extra", 
                         number=10000)
        print '{}: {:6.3} seconds'.format(f.__name__, t)
在我的(iMac)计算机上:


a_list[:-1]
将提供到最后一个元素的列表。我想你想的是一个列表[-1]
@farmergeden,你刚才回答了你自己的问题吗?没有。我知道如何获取列表的最后一个元素。我想要的是一种简单的方法,在遍历列表时,只对最后一个元素执行某些操作。@Farmergeden在循环后加上这个,而不是使用索引,这可能是最简单的方法。你能解释一下“遍历列表”和“在最后一个(并且仅在最后一个)执行某些操作”之间的区别吗元素,而只是使用一个列表[-1]做一些事情?浏览一个列表,然后返回并对最后一个元素做一些事情,而不是在同一个迭代中同时做这两件事,这似乎是一种耻辱。如上所述,这可能建立在情感上;但是当这是真的时,学习是很好的。你也可以做
enumerate(a_list,1)
,然后你不需要在每一步都做减法检查
n==len(a_list)
@mgilson-有用,我不知道。使用
else
块可能是更好的选择。如果我们用
break
明确地中断了循环,那么最后一个元素不应该在IMO中处理。循环结束,我们用
lst
@iCodez完成了——可能是这样。这实际上取决于OP试图解决的问题(尚未很好地定义),这就是我为什么尝试为问题的许多不同变体提供解决方案的原因。:-)
li[:]=[do_somthing(item) for item in li]  # something to every item in place
li[-1]=something_extra(li[-1])            # additional to last item
for i, item in enumerate(li):
    li[i]=do_somthing(item)
    if i==len(li)-1:
        li[i]=something_extra(item)
def do_something(e):
    return e*2

def something_extra(e):
    return e/2

def f1(li):
    for i, item in enumerate(li):
        li[i]=do_something(item)
        if i==len(li)-1:
            li[i]=something_extra(item)

def f2(li):
    li[:]=[do_something(item) for item in li]
    li[-1]=something_extra(li[-1])

def f3(li):
    for i, item in enumerate(li):
        li[i]=do_something(item)
    li[i]=something_extra(item)

if __name__ == '__main__':
    import timeit
    for f in (f1,f2,f3):
        t=timeit.timeit("f(range(1000))", 
                         setup="from __main__ import f,do_something,something_extra", 
                         number=10000)
        print '{}: {:6.3} seconds'.format(f.__name__, t)
f1:   2.95 seconds
f2:   1.45 seconds
f3:   1.97 seconds