【问题标题】:Getting next element while cycling through a list循环遍历列表时获取下一个元素
【发布时间】:2011-01-11 04:35:35
【问题描述】:
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

有更好的方法吗?

【问题讨论】:

  • 考虑省略 while 循环。这似乎与问题无关。如果相关,请考虑解释原因。
  • 我想无限期地循环遍历一个列表,因此是 while/for 循环组合。抱歉,没有解释。
  • 我假设您也希望能够在周期的中间而不是结束时停止?
  • 是的。我确定我可以使用break

标签: python list iteration next


【解决方案1】:
while running:
    for elem,next_elem in zip(li, li[1:]+[li[0]]):
        ...

【讨论】:

  • 这是我的第二个最爱,仅次于我的。 :-) 简单是最好的,但如果列表很大,则会创建两个副本。
【解决方案2】:

您可以使用成对循环迭代器:

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)):
    ...

【讨论】:

  • 这很好。它将 while 循环和 for 循环合并为一个简洁的循环,不断迭代列表中的相邻对,并在最后回绕。
  • +1 用于成对使用 - 一个非官方的库函数,仅存在于 itertools 的文档中。因此,虽然您无法导入它,但它可以正常工作。
  • 我认为在 for 循环中运行测试并要求使用 break 并不是一个好主意。
【解决方案3】:

仔细考虑后,我认为这是最好的方法。它可以让你在不使用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

【讨论】:

  • +1 是的,这也简单有效。对于具有极其简单的程序解决方案的问题,不需要这些不必要的复杂功能解决方案。 Python 不是函数式语言!
  • @Mark Byers,谢谢!如果列表相当小,我确实认为有一个相当实用的解决方案的空间,我补充说。 running 的整个部分都不起作用,并且试图将其硬塞到功能解决方案中是丑陋的。
  • @Mark Byers:在那里,我认为最好的答案是使用 itertools,但以一种非常简约的方式。我认为它非常快速且易于理解。
  • 我是个完美主义者。令人恼火的是,经过 8 次编辑后,它变成了社区 wiki 答案。 叹息
  • 喜欢这个! (idx + 1) % len(li)
【解决方案4】:
while running:
    lenli = len(li)
    for i, elem in enumerate(li):
        thiselem = elem
        nextelem = li[(i+1)%lenli]

【讨论】:

  • 由于某种原因,这是用最后一个元素再次打印列表的第一个元素。
【解决方案5】:

解决这个问题的另一种方法:

   li = [0,1,2,3]

   for i in range(len(li)):

       if i < len(li)-1:

           # until end is reached
           print 'this', li[i]
           print 'next', li[i+1]

       else:

           # end
           print 'this', li[i]

【讨论】:

    【解决方案6】:

    在 Python 中使用 zip 方法。此函数返回一个元组列表,其中第 i 个元组包含来自每个参数序列或可迭代对象的第 i 个元素

        while running:
            for thiselem,nextelem in zip(li, li[1 : ] + li[ : 1]):
                #Do whatever you want with thiselem and nextelem         
    

    【讨论】:

    • 这太棒了!
    • 注意这是创建一个新列表;在处理庞大的列表时可能是您不想做的事情。
    【解决方案7】:
            li = [0, 1, 2, 3]
            for elem in li:
                if (li.index(elem))+1 != len(li):
                    thiselem = elem
                    nextelem = li[li.index(elem)+1]
                    print 'thiselem',thiselem
                    print 'nextel',nextelem
                else:
                    print 'thiselem',li[li.index(elem)]
                    print 'nextel',li[li.index(elem)]
    

    【讨论】:

      【解决方案8】:
         while running:
              lenli = len(li)
              for i, elem in enumerate(li):
                  thiselem = elem
                  nextelem = li[(i+1)%lenli] # This line is vital
      

      【讨论】:

      • 您好,欢迎来到 stackoverflow。请给出解释,而不仅仅是你的答案的代码
      【解决方案9】:

      我使用枚举来处理这个问题。

      storage = ''
      for num, value in enumerate(result, start=0):
          content = value
          if 'A' == content:
              storage = result[num + 1]
      

      我在这里使用 num 作为 Index,当它找到正确的值时,它会将 1 加到实际列表的当前索引中。这让我可以调整到下一个索引。

      我希望这对你的目的有所帮助。

      【讨论】:

        【解决方案10】:

        就这么简单:

        li = [0, 1, 2, 3]
        while 1:
           for i, item in enumerate(x):
              k = i + 1 if i != len(x) - 1 else 0
              print('Current index {} : {}'.format(i,li[k]))
        

        【讨论】:

          【解决方案11】:

          对于从 1(或任何 > 0)到结束的字符串列表。

          itens = ['car', 'house', 'moon', 'sun']
          
          v = 0
          for item in itens:
              b = itens[1 + v]
              print(b)
              print('any other command')
              if b == itens[-1]:
                  print('End')
                  break
              v += 1
          

          【讨论】:

            【解决方案12】:

            简单的解决方案是通过合并条件来删除 IndexError:

            if(index<(len(li)-1))
            

            现在不会出现“索引超出范围”错误,因为不会到达最后一个索引。这个想法是在迭代时访问下一个元素。到达倒数第二个元素时,您可以访问最后一个元素。

            使用 enumerate 方法向可迭代对象(列表、元组等)添加索引或计数器。现在使用 index+1,我们可以在遍历列表时访问下一个元素。

            li = [0, 1, 2, 3]
            
            running = True
            while running:
                for index, elem in enumerate(li):
                    if(index<(len(li)-1)):
                        thiselem = elem
                        nextelem = li[index+1]
            

            【讨论】:

            • 这是一个简洁的解决方案。
            猜你喜欢
            • 2018-07-11
            • 2013-06-07
            • 1970-01-01
            • 2018-09-05
            • 2017-02-08
            • 2014-11-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多