迭代Python列表并在最后一个元素上执行某些操作

时间:2014-06-26 16:01:07

标签: 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

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

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

6 个答案:

答案 0 :(得分:9)

for item in lst:
   do_something_to(item)
else:
   do_something_extra_special_to_last(item)

这里我假设您想要对最后一项执行额外操作(事先仍会对其执行正常操作)。我还假设您没有点击任何break语句(在这种情况下else将不会执行)。当然,你真的不需要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])

答案 1 :(得分:4)

你正在解决问题:)你的做法确实没有。

如果你想循环,你可以找到长度。然后访问最后一件事。或者只是做循环,然后用a_list[-1]做一些事情。花哨的方式,使用for-else - 你可以google它。但是,真的,你的代码没有任何问题。

答案 2 :(得分:2)

您可以使用else block of a for-loop

>>> for i in [1, 2, 3, 4, 5]:
...     print(i)
... else:
...     print(i**2)
...
1
2
3
4
5
25
>>>

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

另请注意,else块仅在循环正常退出而不会遇到break语句时才会运行。这种行为似乎是正确的,因为如果遇到break语句,则显式退出循环并完成列表。

答案 3 :(得分:1)

您可以使用:

a_list[-1]

访问最后一个元素

答案 4 :(得分:1)

我当然更喜欢你出席的两个版本的第二个版本;如果列表中存在重复项,index可能会导致问题,并且每次迭代都是O(n)操作,而lenO(1)

但是,一般来说,因为你想对最后一项做附加(而不是不同的),我只会在{{1循环:

for

即使存在for item in lst: # do something to every element # do something to lst[-1] (与使用break不同),这也会起作用,并影响列表中的最后一项而不是迭代的最后一项 - 这可能是也可能不是期望的行为。< / p>

答案 5 :(得分:0)

考虑:

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

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)

在我的(iMac)机器上:

f1:   2.95 seconds
f2:   1.45 seconds
f3:   1.97 seconds