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