在遍历列表时获取下一元素

75 投票
12 回答
286115 浏览
提问于 2025-04-15 18:40
li = [0, 1, 2, 3]

running = True
while running:
    for elem in li:
        thiselem = elem
        nextelem = li[li.index(elem)+1]

当这个循环到达最后一个元素时,会出现一个叫做IndexError的错误(这是在遍历任何列表、元组、字典或字符串时都会发生的情况)。其实我希望在那时nextelem的值能等于li[0]。我为此想了一个比较麻烦的解决办法。

while running:
    for elem in li:
        thiselem = elem
        nextelem = li[li.index(elem)-len(li)+1]   # negative index

有没有更好的方法来实现这个呢?

12 个回答

7

你可以使用一个成对循环的迭代器:

from itertools import izip, cycle, tee

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

for elem, next_elem in pairwise(cycle(li)):
    ...
21
while running:
    for elem,next_elem in zip(li, li[1:]+[li[0]]):
        ...

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

122

经过仔细思考,我觉得这个方法是最好的。它让你可以在中间轻松退出,而不需要用到 break,我觉得这很重要,而且计算量很小,所以我认为它是最快的。并且,它不要求 li 必须是列表或元组,任何迭代器都可以。

from itertools import cycle

li = [0, 1, 2, 3]

running = True
licycle = cycle(li)
# Prime the pump
nextelem = next(licycle)
while running:
    thiselem, nextelem = nextelem, next(licycle)

我把其他的解决方案留在这里,以备后用。

那些复杂的迭代器在某些地方有用,但在这里就不需要了。用 % 操作符就可以了。

li = [0, 1, 2, 3]

running = True
while running:
    for idx, elem in enumerate(li):
        thiselem = elem
        nextelem = li[(idx + 1) % len(li)]

如果你想无限循环一个列表,那就这样做:

li = [0, 1, 2, 3]

running = True
idx = 0
while running:
    thiselem = li[idx]
    idx = (idx + 1) % len(li)
    nextelem = li[idx]

我觉得这个方法比涉及 tee 的其他解决方案更容易理解,而且可能更快。如果你确定列表的大小不会改变,可以先保存一个 len(li) 的副本,然后用这个。

这样你也可以轻松地在过山车中间下车,而不必等到车厢再回到底部。其他的解决方案(包括你的)都需要你在 for 循环中间检查 running,然后再用 break

撰写回答