遍历给定起点的列表

Iterate Through a List Given a Starting Point

假设你有一个列表,你有一个起点(例如第 3 个索引)。您将如何从该索引开始遍历列表,然后循环返回以访问列表的所有元素?意思是,您可以在列表的中间开始迭代,但是一旦到达末尾,您将从头开始继续,直到列表中的每个元素都被访问过。做这样的事情最干净、最有效的方法是什么?理想情况下,我正在寻找对 python 伪 for x in list starting with i: 有效的东西。

为了返回(不使用 itertools),您必须使用除法运算符的余数:

i = start_index
while i < len(mylist) + start_index:
    print mylist[i % len(mylist)]
    i+=1

甚至更好,正如@jonrsharpe 指出的那样:

for idx in range(len(mylist)):
     print  mylist[(idx + start_index) % len(mylist)]

为了完整起见,并且因为在这种情况下生成器会更高效,正如@Régis B. 所建议的,您可以:

def mygen(lst, start):
    for idx in range(len(lst)):
        yield  lst[(idx + start) % len(lst)]

如果您的列表很大并且您想避免复制列表的某些部分,那么您需要使用自定义迭代器:

def starting_with(arr, start_index):
     # use xrange instead of range in python 2
     for i in range(start_index, len(arr)):
        yield arr[i]
     for i in range(start_index):
        yield arr[i]

for value in starting_with(my_list, 3):
    ...

您可以创建自己的迭代器函数来非常方便(且高效)地执行此操作,如下所示。

重要的是要注意,正如所写的那样,您可以将负索引传递给它,列表的长度有效地添加到该索引中,因此 -2 表示中的倒数第二个项目一个列表——这正是 Python 本身通常处理列表负索引的方式。

try:
    xrange
except NameError:  # Python 3
    xrange = range

def starting_with(start_index, seq):
    if start_index > 0:
        start_index = start_index-len(seq)
    for i in xrange(start_index, len(seq)+start_index):
        yield seq[i]

for value in starting_with(3, my_list):
    ...